Java Programming/Nesting Exceptions

When an exception is caught, the exception contains the stack-trace, which describes the error and shows where the exception happened (i.e. where the problem is and where the application programmer should look to fix the problem). Sometimes it is desirable to catch an exception and throw another exception. If the new exception keeps a reference to the first exception, the first exception is called a nesting exception.

The above code is an example of a nesting exception. When the  is thrown, by passing in the   object reference as a parameter, the   is nested in the newly created , its stack-trace is appended together. When the  is caught, its stack-trace contains the original  's stack-trace.

This is a kind of exception conversion, from one exception to another. For example, calling a remote object using RMI, the calling method has to deal with  which is thrown if something is wrong during the communication. From the application point of view,  has no meaning, it should be transparent to the application that a remote object was used or not. So the  should be converted to an application exception.

This conversion can also hide where the error is originated. The stack-trace starts when the exception is thrown. So when we catch and throw a new exception, the stack-trace starts at when the new exception was thrown, losing the original stack-trace. This was true with the earlier version of Java (before 1.4). Since then, so called cause facility capabilities were built in the  class.

A throwable contains a snapshot of the execution stack of its thread at the time it was created. It can also contain a message string that gives more information about the error. Finally, it can contain a cause: another throwable that caused this throwable to get thrown. The cause facility is also known as the chained exception facility, as the cause can, itself, have a cause, and so on, leading to a "chain" of exceptions, each caused by another.

A cause can be associated with a throwable in two ways: via a constructor that takes the cause as an argument, or via the  method. New throwable classes that wish to allow causes to be associated with them should provide constructors that take a cause and delegate (perhaps indirectly) to one of the  constructors that takes a cause. For example:

Because the initCause method is public, it allows a cause to be associated with any throwable, even a "legacy throwable" whose implementation predates the addition of the exception chaining mechanism to Throwable. For example:

Further, as of release 1.4, many general purpose Throwable classes (for example,  ,  ) have been retrofitted with constructors that take a cause. This was not strictly necessary, due to the existence of the  method, but it is more convenient and expressive to delegate to a constructor that takes a cause.

By convention, class  and its subclasses have two constructors, one that takes no arguments and one that takes a String argument that can be used to produce a detail message. Further, those subclasses that might likely have a cause associated with them should have two more constructors, one that takes a  (the cause), and one that takes a String (the detail message) and a   (the cause).