Question

I'm in a dire situation which is summed up by the following code.

try {
    dangerousCode();    // Declares `throws ExecutionException`
}
catch (ExecutionException ex) {
    handleIt();
    throw ex;
}
catch (RuntimeException ex) {
    handleIt();
    throw new ExecutionException(ex);
}
finally {
    notifyListeners();  // May throw RuntimeException!
}

I would like to stick to the contract of propagating a potential ExecutionException derived from the dangerous code - explicitly thrown, or wrapping a RuntimeException.

However, the listeners in the finally block (which I don't control) may throw another runtime exception. Of course, I would also like to notify the client of this event.

The dilemma: I now have two exceptions on hands.

I could define my own exception type to wrap both exceptions thrown.

class MyExecutionException {
    Throwable getCause();
    Throwable getSecondCause();
}

I was just wondering, is there another way around this issue?

Was it helpful?

Solution

I was just wondering, is there another way around this issue?

Your idea is perfectly fine. Using own classes for try-catch nested in a catch or finally statement is a common practice. In larger applications such constructs are almost unavoidable.

Your class could look like this:

class MyExecutionException extends MyLogicException {
    //what happened in the first place
    Throwable getOriginException();

    // what have we tried?
    Throwable getRecoveryException();

     // more than 1 thing can happen in recovery, order is important, hence list
    List<Throwable> getAllExceptions(); 
}

Such approach lets you have all the information in one place and makes implementing a single place for exception handling and logging very easy. Just make sure you make your exception wrapper/container class as versatile as possible to suit your future needs.

OTHER TIPS

You can use two methods initCause() and getCause(), which can wrap your exception:

Exception e = new Exception();
e.initCause(new Exception());
Throwable t = e.getCause(); //returns Throwable
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top