首页 > 解决方案 > Transient Polly 重试不适用于 HttpResponseMessage

问题描述

嗨,我想暗示波利重试瞬态错误处理我很有趣,但重试对我不起作用,请让我知道我错在哪里。

 var retryPolicy = Policy
        .HandleResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.Unauthorized

                                           || r.StatusCode == HttpStatusCode.GatewayTimeout
                                           || r.StatusCode == HttpStatusCode.RequestTimeout
                                           || r.StatusCode == HttpStatusCode.ServiceUnavailable)
    .WaitAndRetry(3, i => TimeSpan.FromSeconds(2), (result, timeSpan, retryCount, context) =>
    {
        Console.WriteLine($"Request failed with {result.Result.StatusCode}. Waiting {timeSpan} before next retry. Retry attempt {retryCount}");
    });

    retryPolicy.Execute(() =>
   {
        response = FailedOperation();
       return response;

   });

     private static HttpResponseMessage FailedOperation()
    {
 Console.WriteLine("Exception !!!!!");

    throw new HttpResponseException(HttpStatusCode.GatewayTimeout);
    }

标签: c#asp.netasp.net-mvchttp-response-codespolly

解决方案


自定义FailedOperation()方法不涉及任何相关的 .NET 框架/ASP.NET 基础设施,因此您正在测试的代码执行不会神奇地转换:

throw new HttpResponseException(HttpStatusCode.GatewayTimeout); 

到一个HttpResponseMessage与一个StatusCode。Polly 也不这样做(Polly 对任何委托执行都是通用的,与 http 执行无关)。您发布的FailedOperation()方法只是抛出一个HttpResponseException,纯粹而简单。

该策略未声明为要处理HttpResponseException,因此它不处理它。添加这样的子句.Or<HttpResponseException>()

var retryPolicy = Policy
    .HandleResult<HttpResponseMessage>(r => /* etc */)
    .Or<HttpResponseException>();

并且策略应该处理它并使测试代码的行为符合我认为的问题所期望的那样。或者,您可以修改FailedOperation()以返回HttpResponseMessage带有HttpStatusCode策略句柄的 an,并且再次,测试代码应按预期运行。

最后,如果策略是通过HttpClient您保护异步调用,您可能希望使用策略的异步变体,Polly 自述文件中围绕 Http 调用的示例所建议的那样。


推荐阅读