12

Sometimes, you just have to catch Throwable, e.g. when writing a dispatcher queue that dispatches generic items and needs to recover from any errors (said dispatcher logs all caught exceptions, but silently, and then execution is continued on other items).

One best practice I can think of is to always rethrow the exception if it's InterruptedException, because this means someone interrupted my thread and wants to kill it.

Another suggestion (that came from a comment, not an answer) is to always rethrow ThreadDeath

Any other best practices?

ripper234
  • 222,824
  • 274
  • 634
  • 905

4 Answers4

11

Probably the most important one is, never swallow a checked exception. By this I mean don't do this:

try {
  ...
} catch (IOException e) {
}

unless that's what you intend. Sometimes people swallow checked exceptions because they don't know what to do with them or don't want to (or can't) pollute their interface with "throws Exception" clauses.

If you don't know what to do with it, do this:

try {
  ...
} catch (IOException e) {
  throw new RuntimeException(e);
}

The other one that springs to mind is to make sure you deal with exceptions. Reading a file should look something like this:

FileInputStream in = null;
try {
  in = new FileInputStream(new File("..."));;
  // do stuff
} catch (IOException e) {
  // deal with it appropriately
} finally {
  if (in != null) try { in.close(); } catch (IOException e) { /* swallow this one */ }
}
cletus
  • 616,129
  • 168
  • 910
  • 942
  • 2
    +1 on the never swallow a checked exception - even in your 'first pass.' too often these things get overlooked and ultimately submitted to source control. if in doubt, at least print the stack trace. – akf Jul 08 '09 at 11:53
  • If you can't handle it and can't rethrow it, at least print that stack trace! A stack trace in the log is a great help in diagnosing the problem. – starblue Jul 08 '09 at 11:53
  • 1
    The horror of checked Exceptions... catch IOException only to wrap it in a non-checked exception and NOT do anything with it at all? Of course, that's what you have to do in Java, unless you actually know why you're getting the Exception. – Dan Rosenstark Jul 08 '09 at 12:09
  • 7
    -1 The question is about catching throwables and best techniques, it is NOT about swallowing checked exceptions. – Kalecser Aug 17 '10 at 20:50
  • When did Java add catch(Throwable) ? Or has it always been there and I didn't know about it? – Chris S Sep 22 '10 at 11:01
2

Depends on what you are working on.

if you are developing an API to be used by some one else, its better to re-throw the Exception or wrap it into a custom exception of yours and throw.

Whereas if you are developing an enduser application you need to handle this exception and do the needful.

Ratnesh Maurya
  • 706
  • 3
  • 10
2

What about OutOfMemoryError (or perhaps its super class VirtualMachineError)? I can't imagine there is much you can do after something that serious.

ashirley
  • 1,148
  • 1
  • 12
  • 19
  • 1
    If the thread that allocated a lot of objects happens to catch the OutOfMemoryError at a point where the allocated become garbage collectable, the VM can recover. If the objects are still referenced, then yes, there isn't much you can do except quitting or freeing some objects. – Nicolas Nov 25 '11 at 20:17
  • Catch `VirtualMachineError` is tricky because your program is then in an undefined state: http://stackoverflow.com/questions/8728866/no-throw-virtualmachineerror-guarantees – Raedwald Jun 27 '13 at 07:35
1

If you're writing a dispatcher queue, then by the time the exception comes back to you there's no point in doing anything with it other than logging it. The Swing event queue has basically that type of behavior.

Alternatively, you could provide a hook for an "uncaught exception handler," similar to ThreadGroup. Be aware that the handler could take a long time, and end up delaying your dispatcher.

As far as InterruptedException goes: the only thing that cares about that is your dispatch loop, which should be checking some external state to see if it should stop processing.

kdgregory
  • 38,754
  • 10
  • 77
  • 102
  • Why is checking an external state better than using InterruptedException as a signaling mechanism? – ripper234 Jul 08 '09 at 13:39
  • Because InterruptedException simply indicates that someone called interrupt() on the thread. There could be multiple reasons for doing this, not just terminating the current action. And if you do want to use interrupt() to terminate the dispatcher, you certainly don't want to throw it; simply return from run() -- unless, of course, your dispatcher isn't the only thing that thread is doing, but even there, you almost certainly don't want to blindly throw. – kdgregory Jul 08 '09 at 14:04