我有一个应用程序请求经过身份验证的服务,需要通过access_token
.
我的想法是在access_token
过期时使用 Polly 重试。
我在 .NET Core 3.1 应用程序中使用 Refit (v5.1.67) 和 Polly (v7.2.1)。
服务注册如下:
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;
}
}
}
重试策略不起作用!
分析问题,我意识到异常没有被 HttpClient 的DelegatingHandler
. 由于该AddPolicyHandler
语句正在生成一个DelegatingHandler
( PolicyHttpMessageHandler
) 来执行该策略,并且没有在此处捕获异常,因此该策略永远不会执行。我意识到这个问题只发生在可以发送请求的异步场景中。在同步场景中它可以工作(例如:超时)。
为什么内部没有捕获异常DelegatingHandler
?
我附上了一个模拟 Twitter 调用的示例项目。
https://www.dropbox.com/s/q1797rq1pbjvcls/ConsoleApp2.zip?dl=0
外部参考:
https://github.com/reactiveui/refit#using-httpclientfactory
https://www.hanselman.com/blog/UsingASPNETCore21sHttpClientFactoryWithRefitsRESTLibrary.aspx
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-3.1