Exception chaining in Java

If you catch and rethrow exceptions in Java, you probably know about exception chaining already: You simply give the exception you “wrap” as second argument to your Exception like this

try { ... }
catch (Exception e) {
  throw new CustomException("something went wrong", e);
}

and if you look at the stack trace of the newly thrown exception, the original one is listed as “Caused by:”. Now today I had the rather “usual” use case of cleanup up a failing action and the cleanup itself was able to throw as well. So I had two causing exceptions and I wanted to conserve both of them, including their complete cause chain, in a new exception. Consider the following example:

try { ... }
catch (Exception e1) {
  try { ... }
  catch (Exception e2) {
     // how to transport e1 and e2 in a new exception here?!
  }
  throw e1;
}

My idea here was to somehow tack the exception chain of e1 onto the exception chain of e2, but Java offered no solution for this. So I hunted for my own one:

public static class ChainedException extends Exception {
  public ChainedException(String msg, Throwable cause) {
    super(msg, cause);
  }
  public void appendRootCause(Throwable cause) {
    Throwable parent = this;
    while (parent.getCause() != null) {
      parent = parent.getCause();
    }
    parent.initCause(cause);
  }
}

Now I only had to base the exceptions I actually want to chain on ChainedException and was able to do this (in fact I based all of them on this class):

try { ... }
catch (ChainedException e1) {
  try { ... }
  catch (ChainedException e2) {
    e2.appendRootCause(e1);
    throw new ChainedException("cleanup failed", e2);
  }
  throw e1;
}

Try it out yourself – you’ll see the trace of e1 at the bottom of the cause chain of e2. Quite nice, eh?