非错误码100场景仍打印重试失败提示的原因及解决方法
问题原因
当前外层catch (Exception)会捕获所有类型的异常,包括Polly重试策略未处理的异常(即错误码≠100的异常)。
当Get()抛出不含错误码100的异常时,Polly的重试条件不满足(返回false),不会触发重试,直接将异常抛出到外层catch块,导致错误的提示信息被打印。
解决办法
可以通过以下几种方式实现需求:
方式1:在外层catch中过滤异常类型/错误码
在catch块中复用策略的异常校验逻辑,仅当异常符合「错误码=100」条件时,才打印目标提示:
try { var myClass = new MyClass(); await retryPolicy.ExecuteAsync(async () => await myClass.Get()); } catch (Exception ex) { var errorMessage = ex.InnerException?.Message; if (!string.IsNullOrEmpty(errorMessage)) { try { dynamic error = JsonConvert.DeserializeObject(errorMessage); if (error != null && error.errorCode == 100) { Console.WriteLine("Operation failed after 3 times"); return; } } catch { } } // 处理其他异常 Console.WriteLine("Error occurred: " + ex.Message); }
方式2:使用Polly的ExecuteAndCaptureAsync获取执行结果
通过ExecuteAndCaptureAsync可以直接获取策略执行的完整状态,精准判断是否是「重试耗尽且异常符合条件」的情况:
var myClass = new MyClass(); var result = await retryPolicy.ExecuteAndCaptureAsync(async () => await myClass.Get()); if (result.Outcome == OutcomeType.Failure) { var ex = result.FinalException; var errorMessage = ex.InnerException?.Message; if (!string.IsNullOrEmpty(errorMessage)) { try { dynamic error = JsonConvert.DeserializeObject(errorMessage); if (error != null && error.errorCode == 100) { Console.WriteLine("Operation failed after 3 times"); return; } } catch { } } Console.WriteLine("Error occurred: " + ex.Message); }
方式3:扩展Polly策略,标记重试耗尽的异常
自定义专属异常类型,在重试耗尽时抛出该异常,外层catch仅捕获此异常:
// 自定义重试耗尽异常 public class RetryExhaustedException : Exception { public RetryExhaustedException(Exception innerException) : base("Retry exhausted", innerException) { } } // 调整重试策略,在最后一次重试失败时包装异常 var retryPolicy = Policy .Handle<Exception>(ex => { var errorMessage = ex.InnerException?.Message; if (errorMessage == null) return false; try { dynamic error = JsonConvert.DeserializeObject(errorMessage); if (error != null && error.errorCode == 100) { Console.WriteLine("Try to run again..."); return true; } Console.WriteLine("Error occurred: " + ex.Message); return false; } catch (Exception) { Console.WriteLine("Exception Error occurred: " + ex.Message); return false; } }) .WaitAndRetryAsync(2, _ => TimeSpan.FromSeconds(10), (ex, _, __) => { // 重试耗尽时抛出自定义异常 throw new RetryExhaustedException(ex); }); // 执行代码 try { var myClass = new MyClass(); await retryPolicy.ExecuteAsync(async () => await myClass.Get()); } catch (RetryExhaustedException) { Console.WriteLine("Operation failed after 3 times"); } catch (Exception ex) { Console.WriteLine("Error occurred: " + ex.Message); }
内容的提问来源于stack exchange,提问作者user584018
相关产品推荐
相关产品推荐

