UWP中DI结合Refit与Polly处理ApiException编译报错求助
UWP中Refit结合Polly策略注入时类型不匹配错误
我在UWP应用中通过依赖注入配置了Refit客户端与Polly策略,初始代码如下:
var serviceCollection = new ServiceCollection(); serviceCollection .AddRefitClient(typeof(IClassevivaAPI)) .ConfigureHttpClient( (sp, client) => { client.BaseAddress = new Uri(Endpoint.CurrentEndpoint); } ) .AddPolicyHandler( Policy<HttpResponseMessage> .HandleResult(r => r.StatusCode == System.Net.HttpStatusCode.Unauthorized) .RetryAsync(1) );
发现当HTTP响应状态非OK时Refit会抛出ApiException,于是添加了如下Polly策略:
.AddPolicyHandler(Policy<IApiResponse> .Handle<ApiException>() .RetryAsync(2)
编译时出现错误:
error CS1503: Argument 2: cannot convert from 'Polly.Retry.AsyncRetryPolicy<Refit.IApiResponse>' to 'Polly.IAsyncPolicy<System.Net.Http.HttpResponseMessage>'
错误原因
你添加的第二个策略是针对IApiResponse类型的,但当前AddPolicyHandler在HttpClientBuilder链式调用中,要求传入的是处理HttpResponseMessage的策略。因为AddRefitClient之后的HttpClient管道默认基于HttpResponseMessage,而Refit的IApiResponse级别策略需要用特定方式注册,两者类型不匹配导致编译失败。
解决方案
针对这个问题,有两种可行的解决思路:
方案一:注册针对HttpRequestMessage的异常处理策略
要处理Refit抛出的ApiException,需要将策略改为针对HttpRequestMessage类型,适配HttpClientBuilder的要求:
var serviceCollection = new ServiceCollection(); serviceCollection .AddRefitClient<IClassevivaAPI>() .ConfigureHttpClient((sp, client) => { client.BaseAddress = new Uri(Endpoint.CurrentEndpoint); }) // 保留原有针对Unauthorized状态的HttpResponseMessage策略 .AddPolicyHandler(Policy<HttpResponseMessage> .HandleResult(r => r.StatusCode == System.Net.HttpStatusCode.Unauthorized) .RetryAsync(1)) // 添加针对ApiException的策略,改为处理HttpRequestMessage .AddPolicyHandler(Policy<HttpRequestMessage> .Handle<ApiException>() .RetryAsync(2));
方案二:禁用Refit自动抛异常,统一在HttpClient级别处理响应
配置Refit不自动抛出非OK状态的ApiException,这样所有响应状态都可以在HttpClient层面用Polly处理:
var serviceCollection = new ServiceCollection(); serviceCollection .AddRefitClient<IClassevivaAPI>(sp => new RefitSettings { // 关闭Refit自动抛异常,让响应直接进入Polly处理流程 ThrowOnAnyError = false }) .ConfigureHttpClient((sp, client) => { client.BaseAddress = new Uri(Endpoint.CurrentEndpoint); }) // 统一处理所有非成功响应 .AddPolicyHandler(Policy<HttpResponseMessage> .HandleResult(r => !r.IsSuccessStatusCode) .RetryAsync(2)) // 保留原有针对Unauthorized的重试策略 .AddPolicyHandler(Policy<HttpResponseMessage> .HandleResult(r => r.StatusCode == System.Net.HttpStatusCode.Unauthorized) .RetryAsync(1));
内容的提问来源于stack exchange,提问作者Gabboxl
相关产品推荐
相关产品推荐

