Difference between suppressedException and cause

I have my own exception, thrown by my class, BrowserException.
It may be because some internal problem, i.e. UnsupporderEncodingException.

Now I have 2 options:

  1. Throwable.addSuppressed(Throwable exception)
  2. Throwable.initCause(Throwable cause)

In exceptions, what is the difference between suppressedException and cause?
When will I prefer to use each of them?

Jon Skeet

A suppressed exception is one which would have happened if another exception hadn't occurred. I'm only aware of one case where this happens, which is with a try-with-resources statement. The JLS (14.20.3) says:

Resources are closed in the reverse order from that in which they were initialized. A resource is closed only if it initialized to a non-null value. An exception from the closing of one resource does not prevent the closing of other resources. Such an exception is suppressed if an exception was thrown previously by an initializer, the try block, or the closing of a resource.

So suppose you're trying to write to a file stream on a USB stick, and the USB stick is remove. The write call throws an IOException - but so does the close call, because it's trying to flush a buffer. The original exception from the write call will be the one the caller sees, but they'll be able to get at the one thrown by close as a suppressed exception.

An exception has a cause if it's effectively the result of transforming one exception into another. Suppose you're writing a SQL system that talks to the local file system. Your JDBC driver methods can only throw SQLException, so what do you do if your underlying code throws an IOException because it can't read from disk? You may want the details of the IOException to be visible in the SQLException, so you pass that into the constructor of SQLException - the IOException is the cause of the exception.

You're unlikely to ever need to add suppressed exceptions yourself, but creating one exception that's caused by another (typically through the constructor rather than by calling initCause) is reasonably common.


See more on this question at Stackoverflow