Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

There are several reasons why you should never catch Throwable:

  • Throwable covers system exceptions that you can't do anything about and should let bubble up (for instance OutOfMemoryError,

...

  • 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 Throwable and rethrow it you have to declare your method signature as throws Throwable which is a pain.
  • catching Throwable really 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 Exception after logging is ok but you must not rewrap the exception in a RuntimeException (because it hides InterruptedException, see below).

Never catch Exception

Catching Exception is nearly as bad as catching Throwable. Exception covers InterruptedException, which should never be caught lightly. See below.

...

Do something like:

Code Block
java

try {
    stupidMethod();
} catch (NumberFormatException e) {
    // legitimate error treatment
    ...
} catch (InterruptedException e) {
    // restore the interrupted status
    Thread.currentThread().interrupt();
} catch (RuntimeException e) {
    // log.error(e); // not strictly needed, caller can deal with it
    throw e; // avoid wrapping a RuntimeException in another RuntimeException
} catch (Exception e) {
    // log.error(e); // not strictly needed, caller can deal with it
    throw new RuntimeException(e);
}

...

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:

Code Block
java

boolean tx = TransactionHelper.startTransaction();
boolean ok = false;
try {
    doSomething();
    ok = true;
} finally {
    if (tx) {
        if (!ok) {
            TransactionHelper.setTransactionRollbackOnly();
        }
        TransactionHelper.commitOrRollbackTransaction();
    }
}

...