C# - Try/Catch 记录并重新抛出是一种不好的做法?

C# - Try/Catch Log and Rethrow is a bad practice?

我可以看到几个 post 强调在中央位置或进程边界处理异常的重要性是一种很好的做法,而不是在 try/catch 周围乱扔每个代码块。我坚信我们大多数人都理解它的重要性,但是我看到人们仍然以 catch-log-rethrow 反模式结束,主要是因为为了在任何异常期间缓解故障排除,他们想要记录更多上下文特定信息(例如:传递的方法参数),方法是将方法包装在 try/catch/log/rethrow.

周围

有没有正确的方法来实现这一点,同时仍然保持异常处理的良好做法?我听说过像 PostSharp 这样的 AOP 框架,但想知道这些 AOP 框架是否有任何缺点或主要的性能成本。

谢谢!!

四处搜索后,我考虑自己回答:

Try/Catch/throw/log 散落在方法和代码中不是一个好习惯。当你想到这个时,你应该问以下问题:

您具体要如何处理该异常?如果答案是吞下,我会说你需要三思而后行。如果状态因为 catch 块中的吞噬异常而损坏,那么调用堆栈中更高层的某些方法可能会再次抛出异常——现在如何处理这个异常?再次相同的循环?它很快就会把你引向更大的混乱。

当你真的知道你可以用它做一些事情时,你可能很少想立即遵循捕获异常的模式(比如在 sql 超时异常的情况下吞下并重试)你也可能想捕获异常立即以防万一您想在日志中捕获更多上下文特定的详细信息。在那种情况下,捕获并重新抛出新的异常,将原始异常包装为内部异常。

简而言之 - 在应用程序根级别或服务边界级别有异常 handling/logging 是件好事。

话虽如此 - 在集中位置,您还可以配置如何处理特定类型的异常。例如:

作为业务层数据验证的一部分抛出的错误请求异常只会 return 400 个错误请求(在 Web 应用程序的情况下)

如果异常是 SqlException 类型 - 使用一些跟踪 ID 向客户端抛出通用异常并将详细异常记录到 eventlog/db/application 洞察力等

如果业务层的外部系统出现任何异常 - 再次向客户端发送一般异常,并向提供外部服务的系统发送通知电子邮件。

这些只是一些例子,围绕异常处理的良好实践也隐含地促进了良好的设计。例如:为什么不使用安全防护来确保传递给方法的参数不为 null 并抛出 ArgumentNullException 而不是捕获 NullReferenceException 然后通过在方法级别设置 try/catch/log 来捕获参数值。

我在这里发布了有关异常处理和记录良好做法的问题。请检查它是否有很好的辩论和讨论以及各种建议和良好做法。