如何在 Java 中记录异常?

新手上路,请多包涵

在 Java 中记录异常时,我遇到过几次常见问题。似乎有各种不同的类型需要处理。例如,有些包装了其他异常,有些则根本没有消息——只有一个类型。

我见过的大多数代码都使用 getMessage()toString() 记录异常。但这些方法并不总能捕获查明问题所需的所有信息 - 其他方法,如 getCause()getStackTrace() 有时会提供额外信息。

例如,我现在在 Eclipse Inspect 窗口中查看的异常是 InvocationTargetException 。异常本身没有原因,没有消息,没有堆栈跟踪……但是 getCause() 的目标是 InvalidUseOfMatchersException ,并填充了这些详细信息。

所以我的问题是:给定 任何 类型的异常作为输入,请提供一个方法,该方法将输出格式良好的字符串,其中包含有关异常的 所有 相关信息(例如,可能递归调用 getCause() 除其他外? )在发布之前,我几乎要自己尝试一下,但真的不想重新发明轮子-肯定以前一定做过很多次这样的事情……?

原文由 Steve Chambers 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 696
2 个回答

java.util.loggingJava SE 的标准包。它的 Logger 包括一个接受 Throwable 对象的重载日志方法。它将为您记录异常的堆栈跟踪及其原因。

例如:

 import java.util.logging.Level;
import java.util.logging.Logger;

[...]

Logger logger = Logger.getAnonymousLogger();
Exception e1 = new Exception();
Exception e2 = new Exception(e1);
logger.log(Level.SEVERE, "an exception was thrown", e2);

将记录:

 SEVERE: an exception was thrown
java.lang.Exception: java.lang.Exception
    at LogStacktrace.main(LogStacktrace.java:21)
Caused by: java.lang.Exception
    at LogStacktrace.main(LogStacktrace.java:20)

顺便说一句,在内部,这完全符合@philipp-wendler 的建议。请参阅 SimpleFormatter.java 的源代码。这只是一个更高级别的接口。

原文由 flup 发布,翻译遵循 CC BY-SA 3.0 许可协议

--- 提供的 Throwable printStacktrace() 方法有什么问题(因此每个异常)?它显示了您请求的所有信息,包括类型、消息和根异常的堆栈跟踪以及所有(嵌套)原因。在 Java 7 中,它甚至会向您显示有关 try-with-resources 语句中可能发生的“抑制”异常的信息。

当然,您不想写入 System.err ,该方法的无参数版本会这样做,因此请改用可用的重载之一。

特别是,如果您只想获取一个字符串:

   Exception e = ...
  StringWriter sw = new StringWriter();
  e.printStackTrace(new PrintWriter(sw));
  String exceptionDetails = sw.toString();

如果您碰巧使用了很棒的 Guava 库,它提供了一个实用方法来执行此操作: com.google.common.base.Throwables#getStackTraceAsString(Throwable)

原文由 Philipp Wendler 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题