【问题标题】:C# - Try/Catch Log and Rethrow is a bad practice?C# - Try/Catch Log and Rethrow 是一种不好的做法?
【发布时间】:2017-10-29 10:38:34
【问题描述】:

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

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

谢谢!!

【问题讨论】:

    标签: c# logging exception-handling


    【解决方案1】:

    在这里和那里搜索了一下,我考虑自己回答:

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

    你打算如何处理这个异常?如果答案是燕子,我会说你需要三思而后行。如果由于在 catch 块中吞下异常而导致状态损坏,那么调用堆栈中较高的某些方法可能会再次抛出异常 - 现在如何处理此异常?又是同一个周期?它很快就会让你陷入更大的混乱。

    当你真的知道你可以用它做某事时,你可能会谨慎地遵循立即捕获异常的模式(比如在 sql 超时异常的情况下吞下并重试)此外,你可能希望在需要时立即捕获异常在日志中捕获更多特定于上下文的详细信息。在这种情况下,捕获并重新抛出将原始异常包装为内部异常的新异常。

    简而言之 - 在应用程序根级别或服务边界级别进行异常处理/记录是件好事。

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

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

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

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

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

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

    【讨论】:

      猜你喜欢
      • 2012-05-27
      • 2018-07-03
      • 1970-01-01
      • 2016-02-14
      • 1970-01-01
      • 1970-01-01
      • 2012-10-18
      • 2010-10-01
      • 1970-01-01
      相关资源
      最近更新 更多