假设我正在处理`FooException`,但发生了`BarException`。假设它们都是未检查的异常。
我希望在堆栈跟踪中看到以下内容:
如果
我希望在堆栈跟踪中看到以下内容:
com.bar.BarException: Bar Message
at com.baz.BazCode(BazCode.java:123)
...
Caused by: com.foo.FooException: Foo Message
at com.baz.BazCode(BazCode.java:321)
....
Caused by: ...
然而,默认情况下,FooException
的所有记录将从堆栈跟踪中删除。例如:
// In a class written by me
/**
* ...
* @throws FooException if foo happens
* @throws BarException if bar happens
*/
public void upperFrame() {
try {
foo.doSomething();
} catch (FooException foo) {
bar.doSomethingElse();
}
}
// In class Bar (not written by me)
public void doSomethingElse() {
if (someConditionWhichHappensToBeTrueInThisScenario()) {
throw new BarException("Hello Bar World"); // At this point, FooException gets erased from the stack trace
}
}
如果
BarException
有一个(message, cause)
构造函数,那么我可以遵循一种相当粗糙的“手动克隆”过程来实现我的目标:try {
foo.doSomething();
} catch (FooException foo) {
try {
bar.doSomethingElse();
} catch (BarException bar) {
BarException bar2 = new BarException(bar.getMessage(), foo);
bar2.setStackTrace(bar.getStackTrace());
throw bar2;
}
}
然而,如果BarException
没有这样的构造函数(例如ClassCastException
),那么我只能像这样做:
try {
foo.doSomething();
} catch (FooException foo) {
try {
bar.doSomethingElse();
} catch (BarException bar) {
RuntimeException e = new RuntimeException("com.bar.BarException: " + bar.getMessage(), foo);
e.setStackTrace(bar.getStackTrace());
throw e;
}
}
这是非常危险的,因为e
具有错误的类型,因此可能无法被更高层框架正确处理。
在处理这种情况时是否有最佳做法?
bar.getCause().getStackTrace()
吗? - Kasper van den BergFooException
如何丢失。这与创建带有原因的异常无关,而是由方法doSomethingElse
抛出的异常。 - Adam Burley