When an exception occurs during the handling of an exception, only the last exception gets reported, because I can add just one exception to an Error
object. How to report all exception in the final error message?
Example:
class main
{
public static void main (String[] args)
{
try {
// Database.insert ();
throw new Exception ("insert failed");
}
catch (Exception ex1) {
try {
// Database.rollback ();
throw new Exception ("rollback failed");
}
catch (Exception ex2) {
throw new Error ("Can not roll back transaction.", ex2);
}
}
finally {
try {
// Database.close ();
throw new Exception ("close failed");
}
catch (Exception ex3) {
throw new Error ("Can not close database.", ex3);
}
}
}
}
In the example everything fails. The database insert causes ex1
. The rollback causes ex2
. And closing the database causes ex3
. When the program gets executed only the last ex3
gets reported in the Error
object. How to include also ex1
and ex2
to the Error
object? The constructor of Error
accepts just one exception.
The try-catch is the simplest method of handling exceptions. Put the code you want to run in the try block, and any Java exceptions that the code throws are caught by one or more catch blocks. This method will catch any type of Java exceptions that get thrown. This is the simplest mechanism for handling exceptions.
There are three types of exception—the checked exception, the error and the runtime exception.
throws: The throws keyword is used for exception handling without try & catch block. It specifies the exceptions that a method can throw to the caller and does not handle itself. 5. finally: It is executed after the catch block.
The short answer is NO. You would throw an exception if the application can't continue executing with the bad data. In your example, the logic is to display an error message on the front end and Option 2 is the cleaner method for achieving this requirement.
I suggest you to use try-with-resource-statements introduced in Java 7, in conjunction with the AutoCloseable
-interface.
Sidenote: The
Connection
,Statement
andResultSet
fromjava.sql
all implementAutoCloseable
try (Connection c = DriverManager.getConnection(url)) {
// do your inserts
} catch (Exception e) {
throw new Error("Insert failed", e);
}
This will close your connection
or generally the passed AutoCloseable
appropriately. And will handle the shadowing of the exception by using the Throwable.addSuppressed()
method.
What the equivalent looks like in previous versions can be seen on this other question
Your questions also mentiones a rollback which I haven't covered. This can be done by using the before mentioned Throwable.addSuppressed()
method (as pointed out in the comments by tobias_k), though to be honest it gets quite a bit more messy, and doesn't look as nice anymore:
Exception insertException = null;
try (Connection c = DriverManager.getConnection(url)) {
try {
// do your inserts
} catch (Exception e1) {
insertException = e1;
// do your rollback
}
} catch (Exception e2) {
Error error = new Error("Insert failed", insertException);
error.addSuppressed(e2);
throw error;
}
Just for clarification, the inner catch
-block, can only be reached when the insert fails. Where as the outer catch
can be reached, when any of the following throws an exception:
DriverManager.getConnection()
Connection.close()
For a small demo you can visit this link, which illustrates how the stacktrace looks like.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With