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;