Suppose I handle a FooException and a BarException . Suppose both of them are unchecked exceptions.
What I want to see in stacktrace is:
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: ...
However, by default, the entire FooException entry will be deleted from stacktrace. For instance:
// 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 } }
If BarException has a constructor (message, cause) , then I can perform a rather crude process of "manual cloning" to achieve my goal:
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; } }
However, if BarException does not have such a constructor (for example, ClassCastException ), then I will come to the following things:
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; } }
This is dangerous because e is of the wrong type and therefore may not be handled correctly by higher frames.
Is there a βbetter wayβ to handle this situation?