并非所有代码路径都返回 lambda 表达式中的值

问题描述

这是我的代码

var policy = Policy
              .Handle<HttpRequestException>()
              .RetryAsync(1);

HttpResponseMessage httpResponse = null;
await policy.ExecuteAsync(async () =>
{
 httpResponse = await _graphClient.HttpProvider.SendAsync(batchRequest);
});

这工作得很好。我将代码修改为:

var policy = Policy
              .Handle<HttpRequestException>()
              .OrResult<HttpResponseMessage>(r => r.StatusCode == (HttpStatusCode)429)
              .RetryAsync(1);

然后它返回这个错误

并非所有代码路径都返回 Func<Task<HttpResponseMessage>> 类型的 lambda 表达式中的值

解决方法

简而言之,为了让 Polly 能够检查返回值,您需要返回一些东西¯\_(ツ)_/¯

示例

httpResponse = await policy.ExecuteAsync(async () 
    => await _graphClient.SendAsync(new HttpRequestMessage()));
     // ^ this is now returning a HttpResponseMessage

更长的故事

ExecuteAsync 签名的区别如下

// this just expects a task,which can be supplied with an async lamda
public Task ExecuteAsync(Func<Task> action)

与使用 OrResult<HttpResponseMessage> 时相比

// this expects a task<T> and needs a return value
public Task ExecuteAsync(Func<Task<HttpResponseMessage>> action)

或者换一种说法

在您的原始代码中,您只是将 HttpResponse 消息设置为 lambda 的副作用,这使得 ExecuteAsync 解析为重载签名 {{1} }

Func<Task> action

但是,当您使用 await policy.ExecuteAsync(async () => { httpResponse = await _graphClient.HttpProvider.SendAsync(batchRequest); }); 时,没有这种重载,这是有道理的。如果您不提供结果,Polly 将无法检查结果。