如何在Java中记录尽可能多的异常信息?

2022-08-31 12:53:38

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

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

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

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


答案 1

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

例如:

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 的源代码。这只是一个更高级别的接口。


答案 2

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

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

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

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

如果你碰巧使用伟大的番石榴库,它提供了一个实用程序方法来做到这一点:com.google.common.base.Throwables#getStackTraceAsString(Throwable)


推荐