【问题标题】:Printing Exception vs Exception.getMessage打印异常与 Exception.getMessage
【发布时间】:2015-09-29 09:25:05
【问题描述】:

关于异常使用以下两段代码是否有最佳实践。

//code1

} catch (SomeException e) {
    logger.error("Noinstance available!", e.getMessage());
}

//code2
} catch (SomeException e) {
    logger.error("Noinstance available!", e);
}

什么时候应该使用异常的getMessage方法?

【问题讨论】:

  • 几乎一直如此。除非您知道 SomeException 和覆盖的 toString 方法。 e.getMessage() 是标准方式
  • 如果你只记录消息,你不会得到堆栈跟踪,或者嵌套异常应该有一个。记录异常...
  • @TheNeoNoirDeveloper:“几乎一直”什么?首先?我不想丢失有关异常来自何处、原因等的信息。
  • 您应该始终记录整个异常,而不仅仅是消息。否则日志框架无法为您提供整个堆栈跟踪。
  • 这是我的理论,如果 SomeException 是一个特定的异常(我认为它的意思),那么保留捕获异常的完整信息是没有意义的,(日志框架知道在哪里,当然必须在模式中定义),例如,如果我正在捕捉 (FileNotFoundException),那么我知道它是 fileNotFoundException 并且打印整个堆栈只是我不在乎的额外信息。因此 e.getMessage() 已经足够好了。现在有了 IOException 或 Exception,那么我必须知道究竟是什么原因造成的。@JonSkeet 你说什么?

标签: java exception


【解决方案1】:

第一个无法编译,因为方法 error 接受 String 作为第一个参数和 Throwable 作为第二个参数。

e.getMessage() 不是Throwable

代码应该是

} catch (SomeException e) {
    // No stack trace
    logger.error("Noinstance available! " + e.getMessage());
}

对比

} catch (SomeException e) {
    // Prints message and stack trace
    logger.error("Noinstance available!", e);
}

第一个只打印一条消息。第二个也打印整个堆栈跟踪。

是否需要打印堆栈跟踪取决于上下文。

如果您已经知道为什么会抛出异常,那么打印整个堆栈跟踪不是一个好主意。

如果你不知道,最好打印整个strack trace以方便查找错误。

【讨论】:

  • 我正在使用 sl4j 记录器并且我的 code1 编译。为什么会这样
  • 好的,我的信息是用于标准 log4j,但其余的仍然有效
  • 因为 sl4j 有像 .error(String...) .error(String..., Throwable).error(Throwable) 这样的重载方法。 sl4j 的最佳实践、上面的信息以及查看堆栈跟踪的愿望是LOG.error("Something went wrong: {}", e); 这会将整个堆栈跟踪变成一个字符串,并且只使用 1 个日志条目。如果您使用 MDC 日志记录,这非常重要。如果没有 {} 每个 caused by 将是另一个日志条目,没有 MDC 内容。
【解决方案2】:

当您将异常分为业务级别技术异常时,此原型很有用。

对于业务级异常,您只需使用消息,通过记录分析,或者可能是在屏幕上显示含义信息(某些东西不起作用)。

对于技术异常,最好用stacktrace记录错误,找出问题所在,便于调试和解决。

【讨论】:

    【解决方案3】:

    使用堆栈跟踪:

    logger.error("Could not do XYZ because of: " + ex, ex);
    

    没有堆栈跟踪:

    logger.error("Could not do XYZ because of: " + ex);
    

    【讨论】:

      【解决方案4】:

      这取决于您是否需要原始异常 (SomeException) 的堆栈跟踪。如果是,那么 code2 是这里的正确选项。请注意,这是处理这些情况的更常见方式。

      如果您对原始异常不感兴趣,可以使用 code1,但这个不正确。因为您发送的代码将消息作为参数。所以正确的做法是:

      logger.error("Noinstance available! - reason:" + e.getMessage());
      

      【讨论】:

        【解决方案5】:

        你可以试试这个:-

        logger.error(e.getMessage(), e);
        

        返回此 throwable 的详细消息字符串。

        logger.error(e.getLocalizedMessage(),e);
        

        创建此 throwable 的本地化描述。子类可以覆盖此方法以生成特定于语言环境的消息。对于不覆盖该方法的子类,默认实现返回与getMessage()相同的结果。

        在你的情况下,e 只不过是异常的对象......

        getLocalizedMessage() 你需要重写并给出你自己的消息,即本地化消息的含义。

        【讨论】:

          【解决方案6】:

          Exception.printStackTrace() 不应使用,除非您正在调试。

          对于日志记录,使用Exception.getMessage() 肯定更好。另请注意,许多日志框架(例如 Log4j)接受异常作为日志方法的参数(例如 error())并自行解决。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-12-21
            • 1970-01-01
            • 2015-05-04
            • 2021-11-26
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多