We recently had a problem with a Java server application where the application was throwing Errors which were not caught because Error is a separate subclass of Throwable an
Why not catch them all? Then log them, at least you know you have an error. So better catch Throwable/s than Exception/s only.
I'll go a slightly different route from others.
There are many cases where you would want to catch Throwable (mainly to log/report that something evil happened).
However, you need to be careful and rethrow anything that you cannot deal with.
This is especially true of ThreadDeath.
If you ever catch Throwable, be sure to do the following:
try {
...
} catch (SomeExceptionYouCanDoSomethingWith e) {
// handle it
} catch (ThreadDeath t) {
throw t;
} catch (Throwable t) {
// log & rethrow
}
This post won't make the "checked exceptions are bad" people happy. However, what I am basing my answer on is how Java exceptions are intended to be used as defined by the people that created the language.
Quick reference chart:
The reason you should not catch Exception is that it catches all of the subclasses, including RuntimeException.
The reason you should not catch Throwable is that it catches all of the subclasses, including Error and Exception.
There are exceptions (no pun intended) to the above "rules":
For the second one usually it is enough to wrap main, event handling code, and threads with the catch to Throwable and then check the actual type of the exception and deal with it as appropriate.
A lot of the other answers are looking at things too narrowly.
As they say, if you are writing application code, you should not catch Throwable. You can't do anything about it, so allowing the surrounding system (JVM or framework) to handle these issues is best.
However, if you are writing "system code", like a framework or other low-level code then you may very well want to catch Throwable. The reason is to attempt to report the exception, perhaps in a log file. In some cases your logging will fail, but in most cases it will succeed and you will have the information you need to resolve the issue. Once you have made your logging attempt you should then either rethrow, kill the current thread, or exit the entire JVM.
There's at least one case when I think you may have to catch a throwable or a generic exception - if you're running a separate thread to perform a task, you may want to know if the "run" method of the thread has catched some exception or not. In that case, you probably will do something like this:
public void run() {
try {
...
}
catch(Throwable t) {
threadCompletionError = t;
}
}
I am really not sure if it's the best approach, but it works. And I was having a "ClassNotFound" error being raised by the JVM, and it's an error and not an exception. If I let the exception be thrown, I am not sure how to catch it in the calling thread (probably there's a method but I don't know about it - yet).
As for the ThreadDeath method, don't call the "Thread.stop()" method. Call Thread.interrupt and have your thread to check if it was interrupted by someone.
From the Java API documentation:
The class
Exception
and its subclasses are a form ofThrowable
that indicates conditions that a reasonable application might want to catch.An
Error
is a subclass ofThrowable
that indicates serious problems that a reasonable application should not try to catch.
Errors usually are low-level (eg., raised by the virtual machine) and should not be caught by the application since reasonable continuation might not be possible.