我想通过暂时性错误处理实现 polly 重试。我逗乐了波纹管代码应该可以工作,但重试没有触发。
请让我知道我错在哪里。
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);
}
自定义FailedOperation()
方法不涉及任何相关的 .NET 框架/ASP.NET 基础结构,因此您正在测试的代码执行不会神奇地转换:
throw new HttpResponseException(HttpStatusCode.GatewayTimeout);
到一个有StatusCode
的HttpResponseMessage
. Polly 也不会这样做(Polly 是任何委托执行的通用版本,与 http 执行无关(。 您发布的FailedOperation()
方法只是抛出了一个HttpResponseException
,纯粹而简单。
策略未声明为处理HttpResponseException
因此不会处理它。 添加如下.Or<HttpResponseException>()
子句:
var retryPolicy = Policy
.HandleResult<HttpResponseMessage>(r => /* etc */)
.Or<HttpResponseException>();
并且策略应该处理它并使测试代码按照我认为问题所期望的方式运行。 或者,您可以修改FailedOperation()
以返回策略处理HttpStatusCode
的HttpResponseMessage
,同样,测试代码应按预期运行。
最后,如果策略是通过HttpClient
保护异步调用,则需要使用策略的异步变体,如 Http 调用的 Polly 自述文件示例所示。