Polly政策记录异常和重新抛出

MiF*_*vil 5 c# exception-handling polly

我考虑使用 Polly 来创建记录异常和重新抛出的策略.我没有找到允许它开箱即用的现有方法,但我看到的一些选项

倒退

// Specify a substitute value or func, calling an action (eg for logging) if the fallback is invoked.
Policy.Handle<Whatever>()  
 .Fallback<UserAvatar>(UserAvatar.Blank, onFallback: (exception, context) =>  
   {   _logger.Log(exception, context);
       throw exception;
  });
Run Code Online (Sandbox Code Playgroud)

问题:从Fallback抛出异常是否可以?

超时

Policy.Timeout(1, T30meoutStrategy.Pessimistic, (context, timespan, task) =>  
   {        task.ContinueWith(t =>
 { // ContinueWith important!: the abandoned task may very well still be executing, when the caller times out on waiting for it!    
   if (t.IsFaulted      )           
  {             
       logger.Error(context,t.Exception);         
       throw exception;
  }   );    
Run Code Online (Sandbox Code Playgroud)

或者重试

Policy.Handle<DivideByZeroException>().Retry(0, (exception, retryCount) =>   
  {                logger.Error(context,exception);         
throw exception;
  }   );  
Run Code Online (Sandbox Code Playgroud)

问题:是否支持0次重试?

或者KISS并自己编写简单的try/catch.

哪种方法更好?你有什么建议?

mou*_*ler 12

如果你还没有混合使用Polly,那么尝试/ catch似乎最简单.

如果您已经混合使用Polly,FallbackPolicy可以按照您的建议安全地重新使用.该onFallback委托和回退操作或价值不被支配.Handle<>()的政策的条款,所以你可以安全地从内重新抛出异常onFallback委派.

 Policy<UserAvatar>.Handle<Whatever>()  
 .Fallback<UserAvatar>(UserAvatar.Blank, onFallback: (exception, context) =>  
   {   _logger.Log(exception, context);
       throw exception;
  });
Run Code Online (Sandbox Code Playgroud)

你的问题概述的方法TimeoutPolicy只会捕获调用者之前由于超时而离开的代理抛出的异常,并且仅在TimeoutMode.Pessimistic; 并非所有例外.


您的问题概述的方法.Retry(0, ...)不起作用.如果未指定重试,则onRetry不会调用委托.


为了避免再利用的不整洁FallbackPolicy,你也可以LogThenRethrowPolicy在Polly的结构中编写自己的代码. 此提交(添加简单NoOpPolicy)举例说明了添加新策略所需的最低要求.您可以添加类似于NoOpPolicy但仅仅的实现try { } catch { /* log; rethrow */ }


编辑2019年1月:Polly.Contrib现在还包含一个Polly.Contrib.LoggingPolicy,可以帮助解决这个问题.

  • 您知道 LoggingPolicy 的 NuGet 包在哪里吗?我在 GitHub 上没有看到链接,我尝试在 NuGet 中搜索 Polly.Contrib 和 Polly.Contrib.LoggingPolicy。尽管我发现 Polly.Contrib 的一些子包似乎不相关,但这两个包似乎都不存在。 (2认同)

Ali*_*ned 5

https://github.com/App-vNext/Polly-Samples/blob/master/PollyDemos/Async/AsyncDemo02_WaitAndRetryNTimes.cs显示您可以使用该onRetry:选项,至少对于 WaitAndRetryAsync 而言。我还没看过其他人。

HttpPolicyExtensions
.HandleTransientHttpError()
.WaitAndRetryAsync(3,
    retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))  // exponential back-off: 2, 4, 8 etc
                    + TimeSpan.FromMilliseconds(Jitterer.Next(0, 1000)), // plus some jitter: up to 1 second
    onRetry: (response, calculatedWaitDuration) =>
    {
        logger.LogError($"Failed attempt. Waited for {calculatedWaitDuration}. Retrying. {response.Exception.Message} - {response.Exception.StackTrace}");
    }
);
Run Code Online (Sandbox Code Playgroud)

  • 我不想重试,只是记录并重新抛出。 (2认同)