There are many things to say about exception. This page is about what you should not catch, or what to do if you really must.
There are several reasons why you should never catch
Throwablecovers system exceptions that you can't do anything about and should let bubble up (for instance
ThreadDeath). Rethrowing them as a rewrapped exception hides them and doesn't help (and prevents catchers that really know how to deal with them from seeing them).
- up to Java 6, if you catch
Throwableand rethrow it you have to declare your method signature as
throws Throwablewhich is a pain.
Throwablereally means "I don't know what I catch" which is never a good sign. If you don't know then don't catch. Catching and rethrowing
Exceptionafter logging is ok but you must not rewrap the exception in a
RuntimeException(because it hides
InterruptedException, see below).
Exception is nearly as bad as catching
InterruptedException, which should never be caught lightly. See below.
Be careful about
InterruptedException is a very important mechanism in multi-threaded applications to have cooperating stopping of threads. You must never catch
InterruptedException (directly or implicitly through catching
Throwable) without doing some interrupt-specific job or rethrow it not rewrapped. Please read http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html which explains things in detail.
If you catch
InterruptedException and do nothing about the interruption, then it's not possible to have
Thread.interrupt() do its work correctly, which means you'll never be able to do proper timeouts on your threads. Having timeouts on transactions or background work is important for Nuxeo.
If in your method M you call a method P that has
throws InterruptedException in its signature, then that method P has the specific semantics "this method may take some time and be blocking but can still be interrupted", therefore your own method which calls it can also take some time and be blocking and should be willing to be interrupted, and therefore your method M should also have
throws InterruptedException in its signature. Never never swallow
Calling something declared as
In the rare case where you have to call a library method that's badly written and declares that it
throws Exception then you should find out what the actual exception is that you're ready to deal with, let's say
NumberFormatException, and let the others go by rewrapping them in
RuntimeException if you don't have a more specific one declared.
You must still be careful about
InterruptedException and never catch
Do something like:
Rollback on exception
If you do transaction stuff, often you want to rollback when there's been an error.
But you shouldn't try to catch
Exception (or even worse
Throwable) just so you can rollback the transaction if there's been an error. The proper way to do it is by detecting the error without catching anything, using a flag, for instance:
If you really want to log why the rollback happened then you have to know the exception so you have to catch it, so it becomes more complex and you should deal with the
InterruptedException things already mentioned.
As a final note, there are still many places in Nuxeo written before we know about these good patterns, so don't be surprised to see counterexamples in Nuxeo code... In particular we behave badly about
InterruptedException in many places. They should be fixed