...
There are several reasons why you should never catch Throwable:
Throwablecovers system exceptions that you can't do anything about and should let bubble up (for instanceOutOfMemoryError,
...
-
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 asthrows Throwablewhich is a pain.
- catching
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 rethrowingExceptionafter logging is ok but you must not rewrap the exception in aRuntimeException(because it hidesInterruptedException, 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 | ||
|---|---|---|
| ||
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 | ||
|---|---|---|
| ||
boolean tx = TransactionHelper.startTransaction();
boolean ok = false;
try {
doSomething();
ok = true;
} finally {
if (tx) {
if (!ok) {
TransactionHelper.setTransactionRollbackOnly();
}
TransactionHelper.commitOrRollbackTransaction();
}
}
|
...