【问题标题】:When to log a stacktrace for a caught exception何时为捕获的异常记录堆栈跟踪
【发布时间】:2011-11-13 17:48:53
【问题描述】:

我最近问过whether to report the getMessage() text of a caught exception。相当令人惊讶的是,大多数答案都误解了我的问题,并认为我在询问是否报告捕获的异常的堆栈跟踪,这表明这样做被认为是常态。所以我要问一个后续问题。

当您catch 异常时,您应该或不应该在哪些情况下报告堆栈跟踪?通过“报告”,我为您包括asking a logging framework to log the stack-trace

我不是在问是否要报告某事。我在问该报告是否应该包括堆栈跟踪。

【问题讨论】:

    标签: java logging exception-handling


    【解决方案1】:

    我个人尽量遵守这些规则:

    • 如果我能以“可恢复”的方式处理 catch 中的异常(例如 DateFormatException),则无需跟踪堆栈

    • 如果我想重新抛出异常,则不记录堆栈跟踪。 (以链式方式重新抛出以保留此信息)

    • 如果我将 catch 块中的异常作为错误情况(例如 sql 错误)处理,我会记录堆栈跟踪。

    • 如果是运行时异常,我会建议框架(您的或您使用的任何东西)进行跟踪。

    【讨论】:

    • “一个错误案例”:你能澄清一下你认为什么是错误案例吗?
    • “运行时异常”:你的意思是类RuntimeException的异常;也就是说,一个未经检查的异常?
    • “一个错误案例”:任何出乎意料的事情,但这很难解释。例如,乐观锁定异常可能是预期的(即您处理它并显示错误)或意外的(它不应该发生,致命错误,显示堆栈跟踪),具体取决于情况。 “运行时异常”:正如您所怀疑的那样,我会添加一条规则:如有疑问,请跟踪堆栈。
    【解决方案2】:

    这取决于上下文。例如,在解析来自外部系统的输入时,我可能不会记录/报告来自 NumberFormat 的 ParseException,但如果我捕获到处理包含在我的系统边界内的数据的 ParseException,我肯定会这样做,因为这表明一个内部系统状态不一致,而不是输入值验证失败。

    【讨论】:

    • “内部系统状态不一致” = 表示存在错误。
    【解决方案3】:

    - 开发人员 - 如果您遇到错误情况,将需要堆栈跟踪。因此,您需要某种方式将其从 JVM 中取出并传递给您。

    如果您不将其记录到文件中,那么您会怎么做?文件是 JVM 中可用的最可靠的东西,因此您至少应该在将其发送到网络之前将其放在那里。

    【讨论】:

    • “在错误情况下”:你能澄清一下你认为什么是“错误情况”。仅在捕获未经检查的异常时?
    • @Raedwald,在没有预料到异常的情况下。 mcfinnigan 提到了 ParserExceptions - 你很可能不想记录那些(除非它们发生在意想不到的地方)。
    • 所以,你的意思不是 Error (download.oracle.com/javase/6/docs/api/java/lang/Error.html) 类的例外。
    • @Raedwald,不,在代码未预料到异常的情况下。如果发生意外,您需要获得所有帮助来修复它。
    【解决方案4】:

    我通常报告与 GUI 无关的异常。 GUI 异常很常见,在繁重的 Swing 程序中通常会发生。

    一般来说,我对以下方面非常感兴趣:与数据库相关的异常、我自己的愚蠢错误异常(数组越界等)以及其他一些我无法处理的事情,例如 WebServices 等.

    我认为这取决于系统的类型,是公共系统(如网站)还是私有系统(内联网站点、本地 GUI)

    【讨论】:

    • “My-own-stupid-errors exceptions”:你的意思是未经检查的异常?
    • 这取决于您报告异常的方式。如果您在 try-catch 块中执行此操作,则难以记录未经检查的异常。但是,您可以有更多类似的高级异常,例如将负整数分配给员工 ID,并且您可能希望引发异常。
    【解决方案5】:

    堆栈跟踪对于想要调试异常指示的错误的程序员很有用。它对其他人没有用处,对其方法名称和调用顺序毫无意义,冗长令人分心。因此,您应该记录堆栈跟踪当且仅当且始终如果异常指示程序中的错误。但是,这并不总是表明您编写的方法应该catch 并记录异常。在实践中,错误由未经检查的异常指示,因此让异常从方法中抛出并在更高级别处理更容易(通常更好):如果您使用的是框架,它可能会记录异常您(通常带有其他有用的信息); JVM 本身可能会记录从main 抛出的任何异常。

    【讨论】:

      【解决方案6】:

      我会报告所有这些。但是,如果您使用的是 log4j,那么您可以控制哪些您知道您肯定不会有兴趣在日志中看到。如果特定用户异常具有不同的类,则在生产中禁用登录该类并在较低环境中启用它。这样,您就不会在代码级别做任何事情来进行报告。所有这些都在日志框架中抽象出来。

      【讨论】:

      • “你没有在代码级别做任何报告”:将决定从编程时间推迟到配置时间,但问题仍然存在:你报告堆栈跟踪?
      • 我通常在异常的构造函数中记录异常。在这种情况下,我不需要明确记录任何内容。我实例化异常的那一刻,它就会被记录下来。因此我说,如果您不想报告特定异常,请确保在 log4j 属性中禁用它。对于最初的问题,我认为您肯定希望在 dev 中报告所有异常,然后在 prod 中禁用其中的大部分。
      • “在我实例化异常的那一刻,它就被记录”:这是针对异常的全部点,即将错误处理(抛出部分)的检测和启动与处理和报告的完成分开(捕捉部分)。
      猜你喜欢
      • 2013-02-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-08
      • 2011-03-29
      • 1970-01-01
      相关资源
      最近更新 更多