Throwing multiple exceptions in Java
A method can throw one of several exceptions. Eg:
public void dosomething() throws IOException, AWTException < // . >
This signals that the method can eventually throw one of those two exceptions (and also any of the unchecked exceptions). You cannnot (in Java or in any language AFAIK) throw simultaneously two exceptions, that would not make much sense.
You can also throw a nested Exception, which contains inside another one exception object. But that would hardly count that as «throwing two exceptions», it just represents a single exception case described by two exceptions objects (frequently from different layers).
That depends on the point of view 😉 The obviously does not answer the question how multiple exceptions can be thrown.
You can’t throw two exceptions. I.e. you can’t do something like:
try < throw new IllegalArgumentException(), new NullPointerException(); >catch (IllegalArgumentException iae) < // . >catch (NullPointerException npe) < // . >
Alternative 1: Exception A is caused by exception B
You could nest exceptions using the cause-constructor to do the following:
try < Exception ex1 = new NullPointerException(); // Throw an IllegalArgumentException that "wraps" ex1 throw new IllegalArgumentException(ex1); >catch (IllegalArgumentException iae) < // handle illegal argument. throw iae.getCause(); // throws the cause (the NullPointerException) >
Alternative 2: Use suppressed exception
One exception can suppress another exception.
try < Exception ex1 = new NullPointerException(); // Throw an IllegalArgumentException that "suppresses" ex1 IllegalArgumentException ex2 = new IllegalArgumentException(); ex2.addSuppressed(ex1); throw ex2; >catch (IllegalArgumentException iae) < // handle illegal argument. . iae.getSuppressed() . // get hold of the suppressed exceptions >
I suppose you could create an exception containing a list of caught exceptions and throw that exception, e.g.:
class AggregateException extends Exception < Listbasket; >
Throwing more than a single exception doesn’t make sense because you can’t have more than a single error (the error can have multiple reasons but there can’t be more than a single error at any time).
If you need to keep track of the reasons, you can chain exceptions:
These are available via getCause() .
Please don’t encourage people to catch the base Exception . Also, for repackaging exceptions, I a project specific exception base class. This way I can differentiate between acceptable exceptions, ones I have already wrapped and am planning for, and an unexpected exception.
Depends on what you mean by error. In the specific case of developing a semantic analyser for a given language, the AST could possibly contain multiple semantic errors which would be beneficial to return «all at once» to the user, to avoid them having to compile the code to see the next error that pops up again and again. You could argue that this case doesn’t require exceptions, and a simple String could suffice.
@Novicegrammer: My design for this is that there is a single exception which contains a list of errors and the message is «There were » + errors.size() + » errors:\n» + errors.stream().map(String::valueOf).collect(joining(«\n»)
I’ve seen a pattern, where a custom exception internally stores other exceptions (can’t remember, why they did it), but it was like:
public class ContainerException extends Exception < private ListinnerExeptions = new Arrayist(); // some constructors public void add(Exception e) < innerExceptions.add(e); >public Collection getExceptions() < return innerExceptions; >>
and it was used like this:
try < // something >catch (ContainerException ce) < ce.add(new RunTimeException("some Message"); throw ce; // or do something else >
Later in the code, the container exception was evaluated and dumped to a log file.
To throw multiple exceptions in Java you’ll first have to suppress each exception into one customized exception and then throw the same customized exception. Please check the below code snippet to achieve the same.
public class AggregateException extends Exception < public void addException(Exception ex)< addSuppressed(ex); exception = true; >> public class AnyClass< public AggregateException aggExcep = new AggregateException(); public void whereExceptionOccurs()< try< //some code >catch(Exception e) < aggExcep.addException(e); //throw aggExcep; >> >
Call the method addException with the same reference aggExcep wherever you want to(Inside the catch block obviously) suppress any exception. And at the end explicitly throw aggExcep using ‘throw’ keyword where ever you want to.
void addSuppressed(Throwable exception)
is a predefined method of Throwable class which appends the specified exception to the exceptions that were suppressed in order to deliver this exception.
You can have the possibility of throwing multiple different exceptions. For example:
if (obj == null) throw new NullPointerException(); if (some other case) throw new IllegalArgumentException(); if (this == this) throw new IOException();
This code may throw multiple different exceptions, but this can never happen at the same time.
The pattern described by Andreas_D is definitely useful whenever you’re handling, say, the server-side compilation of a user-provided file and want to report back the errors.
For example, you might have a CompilationException which gets generated if the resource fails to compile. Compiling might mean any number of things. For example, you might evaluate the text inside of a file that an end user uploads, parse out tokens, check for syntax errors and determine whether the file is valid. At the end, the thing is either valid or it is invalid and you want to hand back a proper CompilationException to propagate back up the call stack.
Like Andreas describes, you can have an add() method that lets you add compilation issues to your exception. Those issues don’t have to be Exceptions themselves, but that’s up to you. It often helps to stick to a single exception framework so that you can use the same validation logic in multiple places.
At any rate, what you want is a single CompilationException falling back through the call stack because that tells the framework that the thing did not compile. If anyone up the chain wants to know why, then they can get at the underlying issues with a call to, say, getCauses().
It’s also useful from a UI perspective. That information sticking around on the Exception can be properly handled before going back over the wire so that you can give your end user some information as to why the compilation failed.
Chained Exceptions
An application often responds to an exception by throwing another exception. In effect, the first exception causes the second exception. It can be very helpful to know when one exception causes another. Chained Exceptions help the programmer do this.
The following are the methods and constructors in Throwable that support chained exceptions.
Throwable getCause() Throwable initCause(Throwable) Throwable(String, Throwable) Throwable(Throwable)
The Throwable argument to initCause and the Throwable constructors is the exception that caused the current exception. getCause returns the exception that caused the current exception, and initCause sets the current exception’s cause.
The following example shows how to use a chained exception.
In this example, when an IOException is caught, a new SampleException exception is created with the original cause attached and the chain of exceptions is thrown up to the next higher level exception handler.
Accessing Stack Trace Information
Now let’s suppose that the higher-level exception handler wants to dump the stack trace in its own format.
Definition: A stack trace provides information on the execution history of the current thread and lists the names of the classes and methods that were called at the point when the exception occurred. A stack trace is a useful debugging tool that you’ll normally take advantage of when an exception has been thrown.
The following code shows how to call the getStackTrace method on the exception object.
catch (Exception cause) < StackTraceElement elements[] = cause.getStackTrace(); for (int i = 0, n = elements.length; i < n; i++) < System.err.println(elements[i].getFileName() + ":" + elements[i].getLineNumber() + ">> " + elements[i].getMethodName() + "()"); > >
Logging API
The next code snippet logs where an exception occurred from within the catch block. However, rather than manually parsing the stack trace and sending the output to System.err() , it sends the output to a file using the logging facility in the java.util.logging package.
try < Handler handler = new FileHandler("OutFile.log"); Logger.getLogger("").addHandler(handler); >catch (IOException e) < Logger logger = Logger.getLogger("package.name"); StackTraceElement elements[] = e.getStackTrace(); for (int i = 0, n = elements.length; i < n; i++) < logger.log(Level.WARNING, elements[i].getMethodName()); >>
java chain exception
Be aware that in most cases if you don’t know how to handle the exception it’s better to just let it propagate. You really only need to chain exceptions if letting an exception propagate would expose implementation details to the caller.
4 Answers 4
You’ll need to declare that the method throws another exception, if the exception is a checked exception.
(«The unchecked exceptions classes are the class RuntimeException and its subclasses, and the class Error and its subclasses. All other exception classes are checked exception classes.» — Java Language Specification, Second Edition, Section 11.2)
void someMethod < try < // Do something that raises an Exception. >catch (Exception e) < throw new SomeException(); // Compile error. >>
A throws needs to be added to the method declaration:
void someMethod throws SomeException < try < // Do something that raises an Exception. >catch (Exception e) < throw new SomeException(); // No problem. >>
It depends if SomeException is a checked exception or not. If it is (it extends Exception but not RuntimeException) then you have to declare it on the method or throw a RuntimeException instead.
This is what your code should look like:
. ) throws SomeException < . try < . >catch (Exception e)
If some exception doesn’t have a constructor which takes an exception, then do this:
throw (SomeException) new SomeException().initCause(e);
That way when the exception is ultimately caught, you know the root cause of the problem.