31 May 2011

Thoughts on catching general exception types

Discussed here and all over the web.

So what are the arguments?

Pros

  • obviously less code, including code repetition when handling several specific types of exceptions requires the same actions
  • as a direct result of less code repetition we have lesser probability of bad code change propagation (changes that need to be made in two similar blocks of code, but are only made to one of them)
Unfortunately, to me, that comes at a very high cost.

Cons
  • improper handling of generic exceptions that would normally indicate a bug (NullPointerException, ClassCastException etc.); these exceptions need to be handled in a different way than NumberFormatException or some application level exception (which might make sence to the user, for instance indicating that the input needs to be numeric)
  • another more subtle and very dangerous problem is exception swallowing; if you enforce the rule to not catch generic exceptions you also avoid swallowing them - even if the developer is unwise enough to make an empty catch block it would only catch the specific exception; on the other hand if he makes an empty catch block that catches Throwable ... you've got a much bigger problem on your hand
  • the above issues are even more serious when the code you are trying to handle the exception in is actually a public library or framework; handling a OutOfMemoryError for example makes no sense whatsoever in this context; normally you would want the client code to receive this exception and perhaps handle it (although it might be even better to not handle it at all because in most cases the application would not be able to recover from such an exception)

Generally speaking

I am not really a fan of strict coding rules. I would actually prefer to not bind the developer too much, but I find this a matter of approach rather than choice. I know that the code is not written in the best way when it handles generic exceptions - a well written application would have a well defined exception handling model. It would have checked exceptions it could handle (display a message or react in some other way) and unchecked exceptions that would normally indicate a bug.

Bugs are unfortunate, but they need to be visible - hiding the actual issue from the user does not remove the bug itself. I mean having your user click on a button and not reacting is no better than displaying an error message. And after all if it is the error message itself that you want to concentrate on - you could always make a generic catch block in your most outer layers of UI and display a friendly error. Much better than having one of your developers loose two days of debugging just to find the following line of code in the storage layer :

try {
   if(entity == null){
       entity.setDirty();
       session.save(entity);
   }
} catch (Exception) {
   // TODO perhaps we should handle this at some point, but not now
}