I have an application that makes a request for an authenticated service, where it is necessary to pass the access_token
.
My idea is to use Polly to retry if the access_token
is expired.
I'm using Refit (v5.1.67) and Polly (v7.2.1) in a .NET Core 3.1 application.
The services are registered as follows:
services.AddTransient<ExampleDelegatingHandler>();
IAsyncPolicy<HttpResponseMessage> retryPolicy = Policy<HttpResponseMessage>
.Handle<ApiException>()
.RetryAsync(1, (response, retryCount) =>
{
System.Diagnostics.Debug.WriteLine($"Polly Retry => Count: {retryCount}");
});
services.AddRefitClient<TwitterApi>()
.ConfigureHttpClient(c =>
{
c.BaseAddress = new Uri("https://api.twitter.com/");
})
.AddHttpMessageHandler<ExampleDelegatingHandler>()
.AddPolicyHandler((sp, req) =>
{
//this policy does not works, because the exception is not catched on
//"Microsoft.Extensions.Http.PolicyHttpMessageHandler" (DelegatingHandler)
return retryPolicy;
});
public interface TwitterApi
{
[Get("/2/users")]
Task<string> GetUsers();
}
public class ExampleDelegatingHandler : DelegatingHandler
{
protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
try
{
return await base.SendAsync(request, cancellationToken);
}
catch (Exception)
{
//Why do not catch the exception?
throw;
}
}
}
The retry policy is not working!
Analyzing the problem, I realized that the exception is not being caught inside the HttpClient's DelegatingHandler
. Since the AddPolicyHandler
statement is generating a DelegatingHandler
(PolicyHttpMessageHandler
) to execute the policy and the exception is not caught there, the policy never executes. I realized that the problem only occurs in asynchronous scenarios, where the request can be sent. In synchronous scenarios it works (example: timeout).
Why the exception is not caught inside DelegatingHandler
??
I am attaching an example project simulating a Twitter call.
https://www.dropbox.com/s/q1797rq1pbjvcls/ConsoleApp2.zip?dl=0
External references:
https://github.com/reactiveui/refit#using-httpclientfactory
https://www.hanselman.com/blog/UsingASPNETCore21sHttpClientFactoryWithRefitsRESTLibrary.aspx
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-3.1