Recently, I met some exception problem in java, which reminded me of the typical idiom recommended by Bruce Eckel:
Converting checked to unchecked exceptions
The real problem is when you are writing an ordinary method body, and you call another method and realize, "I have no idea what to do with this exception here, but I don’t want to swallow it or print some banal message." With chained exceptions, a new and simple solution prevents itself. You simply "wrap" a checked exception inside a RuntimeException by passing it to the RuntimeException constructor, like this:
try { // ... to do something useful } catch (IDontKnowWhatToDoWithThisCheckedException e) { throw new RuntimeException(e); }This seems to be an ideal solution if you want to "turn off the checked exception—you don’t swallow it, and you don’t have to put it in your method’s exception specification, but because of exception chaining you don’t lose any information from the original exception.
This technique provides the option to ignore the exception and let it bubble up the call stack without being required to write try-catch clauses and/or exception specifications.
However, I found it didn't work in some cases. as seen here:
package exceptions; // How an exception can be lost class VeryImportantException extends Exception { @Override public String toString() { return "A very important exception"; } } class HoHumException extends Exception { @Override public String toString() { return "A trivial exception"; } } public class LostMessage { void f() throws VeryImportantException { throw new VeryImportantException(); } void dispose() throws HoHumException { throw new HoHumException(); } public static void main(String[] args) { try { LostMessage lm = new LostMessage(); try { lm.f(); } catch (VeryImportantException e) { throw new RuntimeException(e); } finally { lm.dispose(); } } catch (Exception e) { throw new RuntimeException(e); } } }/* Output: Exception in thread "main" java.lang.RuntimeException: A trivial exception at exceptions.LostMessage.main(LostMessage.java:36) Caused by: A trivial exception at exceptions.LostMessage.dispose(LostMessage.java:23) at exceptions.LostMessage.main(LostMessage.java:33) *///:~ As the output demonstrated, the second exception completely obliterates the first one. There is no record of the first exception in the exception stack trace, which can greatly complicate debugging in real systems. usually, it’s the first exception that you want to see in order to diagnose the problem.
Joshua Bloch recommends the try-with-resource way that a resource must implement the AutoCloseable interface, which process is somewhat complex.
So, my question is this: is there any way I can use to make sure that exception will not lose its stack trace information by Bruce Eckel's approach?
try/catcharound themainMethod and in the catch you perform the traversing of thecause-list on your own and write the stac trace for all of them?try/catchin real code.