1. Overview
The throw keyword in Java is used to explicitly throw either a custom-made exception or in-built exception. But sometimes in the catch block, we need to throw the same exception again. This leads to re-throwing an exception.
In this tutorial, we'll discuss the two most common ways of re-throwing the exception.
2. Re-throwing Exceptions
Sometimes before propagating the exception to the higher level, we might want to perform some activities. For example, we might want to rollback the DB transaction, log the exception, or send an email.
We can perform such activities in the catch block and re-throw the exception again. In this way, a higher level gets notified that the exception has occurred in the system.
Let’s understand our case with an example.
Below, we're re-throwing the same exception. And, we're logging an error message just before throwing it:
String name = null; try { return name.equals("Joe"); // causes NullPointerException } catch (Exception e) { // log throw e; }
The console will show the following message:
Exception in thread "main" java.lang.NullPointerException at com.baeldung.exceptions.RethrowSameExceptionDemo.main(RethrowSameExceptionDemo.java:16)
As we can see, our code just rethrows any exception it catches. Because of this, we get the original stack trace without any changes.
3. Wrapping Exceptions
Now, let's take a look at a different approach.
In this case, we'll pass the same exception as a reference in the constructor of a different exception:
String name = null; try { return name.equals("Joe"); // causes NullPointerException } catch (Exception e) { // log throw new IllegalArgumentException(e); }
The console will display:
Exception in thread "main" java.lang.IllegalArgumentException: java.lang.NullPointerException at com.baeldung.exceptions.RethrowDifferentExceptionDemo.main(RethrowDifferentExceptionDemo.java:24) Caused by: java.lang.NullPointerException at com.baeldung.exceptions.RethrowDifferentExceptionDemo.main(RethrowDifferentExceptionDemo.java:18)
This time, we see the original exception as well as the wrapping one. In this way, our IllegalArgumentException instance wraps the original NullPointerException as a cause. Hence we can show the more specific exception instead of showing the generic one.
4. Conclusion
In this short article, we presented the main difference between re-throwing the original exception vs first wrapping it. Both ways differ from each other in the way they show the exception message.
Based on our requirement, we can either re-throw the same exception or wrap it with some specific exception by using the second approach. The second approach looks cleaner and easy to backtrack the exception.
As always the project is available over on GitHub.