c# - Polly 回退操作未引发指定的异常。发生了什么?
问题描述
鉴于此代码尝试调用AuthenticationManager.Authenticate()
10 次,然后在 10 次CustomException
尝试失败后抛出:
string res = Policy
.Handle<Exception>() // Handles any exception
.OrResult<string>(result => string.IsNullOrWhiteSpace(result)) // or if result is null
.Fallback(() => throw new CustomException("Exception!")) // Not being thrown after 10 unsuccessful attempts
.Wrap(
Policy
.Handle<Exception>()
.OrResult<string>(result => string.IsNullOrWhiteSpace(result))
.WaitAndRetry(
10,
retryAttempt => TimeSpan.FromSeconds(60),
onRetry: (response, delay, retryCount, context) => Trace.WriteLine($"[{DateTime.UtcNow}] Authentication failed. Retrying after 60 seconds...(Attempt {retryCount} of 10)")))
.ExecuteAndCapture(() => AuthenticationManager.Authenticate())
.Result;
为什么CustomException
没有从后备动作中抛出?正确的方法应该是什么?
解决方案
这些单元测试通过:(xUnit)
[Fact]
public void Test1()
{
var policy = Policy<string>
.Handle<Exception>()
.OrResult(result => string.IsNullOrWhiteSpace(result))
.Fallback(() => throw new CustomException())
.Wrap(
Policy<string>
.Handle<Exception>()
.OrResult(result => string.IsNullOrWhiteSpace(result))
.WaitAndRetry(
10,
_ => TimeSpan.FromSeconds(1),
onRetry: (response, delay, retryCount, context) => Trace.WriteLine($"[{DateTime.UtcNow}] Authentication failed. Retrying after 1 second...(Attempt {retryCount} of 10)")
)
);
var result = policy.ExecuteAndCapture(() => throw new Exception("Muh"));
Assert.IsType<CustomException>(result.FinalException);
Assert.Null(result.Result);
Assert.Equal(OutcomeType.Failure, result.Outcome);
}
[Fact]
public void Test2()
{
var policy = Policy<string>
.Handle<Exception>()
.OrResult(result => string.IsNullOrWhiteSpace(result))
.Fallback(() => throw new CustomException())
.Wrap(
Policy<string>
.Handle<Exception>()
.OrResult(result => string.IsNullOrWhiteSpace(result))
.WaitAndRetry(
10,
_ => TimeSpan.FromSeconds(1),
onRetry: (response, delay, retryCount, context) => Trace.WriteLine($"[{DateTime.UtcNow}] Authentication failed. Retrying after 1 second...(Attempt {retryCount} of 10)")
)
);
Assert.Throws<CustomException>(() => policy.Execute(() => throw new Exception("Muh")));
}
所以,我想,你可以使用Execute
,或者检查结果并重新抛出异常,如下所示:
var result = policy.ExecuteAndCapture(() => AuthenticationManager.Authenticate());
if( result.Outcome == OutcomeType.Failure && result.FinalException is not null)
{
throw result.FinalException;
}
return result.Result;
推荐阅读
- javascript - 如何渲染带有隐藏预设痕迹的情节图,即基于列表的“legendonly”
- erlang - 如何计算erlang中列表内容的长度?
- string - 如何在 Dart 中获取字符串的字节数?
- python - Python中的快速整数矩阵零空间?
- c# - AdMob 横幅广告未显示且未显示说明
- android - Ionic 4 离子菜单不适用于 Android 4.4.2
- vba - 使用 SQL UPDATE 访问 VBA
- r - 为什么 rbind 与具有超过 254 列的 data.table 重新排序列名
- python - 二维列表评估如果比
- python-3.x - 将 html+hex 电子邮件地址转换为可读字符串 Python 3