If I understand your workflow correctly then you don't need the retry policy at all. The Fallback policy is enough for this.
So, let suppose that the CallApi and CallAnotherApi are implemented like this:
private static HttpClient client = new HttpClient();
public static async Task<HttpResponseMessage> CallAPI()
{
return await client.GetAsync("http://httpstat.us//408");
}
public static async Task<HttpResponseMessage> CallAnotherAPI()
{
var response = await client.GetAsync("http://httpstat.us//500");
response.EnsureSuccessStatusCode();
return response;
}
- I've used
httpstatus.us to simulate certain http status codes
CallApi will always fail with Request Timeout
CallAnotherApi will always throw HttpRequestException because of the Ensure method call
Now let's see the policy definition and usage:
public static async Task Main(string[] args)
{
var fallbackPolicy = Policy<HttpResponseMessage>
.HandleResult(msg => msg.StatusCode == HttpStatusCode.RequestTimeout)
.FallbackAsync(async (_) => await CallAnotherAPI());
HttpResponseMessage result;
try
{
result = await fallbackPolicy
.ExecuteAsync(async () =>
{
return await CallAPI();
});
}
catch (Exception ex) {
Console.WriteLine(ex.Message); //TODO: replace with logging
throw;
}
Console.WriteLine(result.StatusCode);
}
- The fallback policy should be triggered only if the response's status code was 408
ExecuteAsync will throw exception if either the CallApi or CallAnotherApi throws
Let's see the different scenarios one-by-one
CallApi succeeds
public static async Task<HttpResponseMessage> CallAPI()
{
return await client.GetAsync("http://httpstat.us//200");
}
Output
OK
CallApi fails
public static async Task<HttpResponseMessage> CallAPI()
{
var response = await client.GetAsync("http://httpstat.us//500");
response.EnsureSuccessStatusCode();
return response;
}
Output
Response status code does not indicate success: 500 (Internal Server Error).
Then the application crashes because of throw;
CallApi timeouts and CallAnotherApi succeeds
public static async Task<HttpResponseMessage> CallAPI()
{
return await client.GetAsync("http://httpstat.us//408");
}
public static async Task<HttpResponseMessage> CallAnotherAPI()
{
var response = await client.GetAsync("http://httpstat.us//200");
response.EnsureSuccessStatusCode();
return response;
}
Output
OK
CallApi timeouts and CallAnotherApi fails
public static async Task<HttpResponseMessage> CallAPI()
{
return await client.GetAsync("http://httpstat.us//408");
}
public static async Task<HttpResponseMessage> CallAnotherAPI()
{
var response = await client.GetAsync("http://httpstat.us//500");
response.EnsureSuccessStatusCode();
return response;
}
Output
Response status code does not indicate success: 500 (Internal Server Error).
Then the application crashes because of throw;