How to (not) handle Java Exceptions

The last couple of days I was digging my way through OpenJDK’s AWT/Java2D/Font2D code and found a couple of antipatterns regarding Exception handling that really stole a lot of my time. I’d like to outline them and show sane alternatives that would have saved a lot of my time.

Ignoring exceptions

This is the most stupid, and frankly, the most widespread antipattern for exception handling, probably often a result of a combination of laziness and the need to handle checked exceptions:

try {
  // do something
} catch (SomeCheckedException ex) {
  // dunno what to do with this.
  // or even worse:
  // Should never happpen.
}

Really. Never ever do this. In the (possibly rare) case, that the application runs into this, it most likely ends up in an undefined state, and makes debugging a pain. (‘Hey, how does the VM get out of this method without returning? Duh! A swallowed exception!’ is usually my train of thoughts) At least, print out the exception:

catch (SomeException ex) {
  ex.printStackTrace();
  // maybe use logger to log this.
}

If you don’t know how to handle the exception, and don’t want to just swallow it, you could wrap it into an unchecked exception or even error (depending if you think this is an exceptional or error condition):

catch (SomeException ex) {
  SomeRuntimeException rte = new SomeRuntimeException();
  rte.initCause(ex);
  throw rte;
}

The replaced exception

I also see this pattern from time to time:

try {
  // do something.
} catch (SomeException ex) {
  throw new SomeOtherException(ex.getMessage());
}

This is only little more useful than swallowing the exception completely. Again, wrapping the exception properly is a much more helpful solution, as it gives the poor developer soul at least a stacktrace to work with:

catch (SomeException ex) {
  SomeOtherException ex2 = new SomeOtherException(ex.getMessage());
  ex2.initCause(ex);
  throw ex2;
}

There are certainly more such antipatters, these are only two of them that stole a lot of my time. If you know more, please comment and add them below.

Advertisements

5 Responses to How to (not) handle Java Exceptions

  1. Uzytkownik says:

    I’m not sure but I think in most exceptions (standard) you can do:
    catch (SomeException ex) {
    throw new SomeOtherException(ex);
    }
    Which will print both stacks.

  2. Ismael Juma says:

    Hi,

    You’re obviously right that swallowing exceptions is very bad practice, but in most cases you can rethrow an exception with just one line instead of three by passing the cause in the constructor (which eliminates the need for the temporary variable). Of course this only works with exceptions that take a Throwable in the constructor, but this is quite common from my experience.

    Regards,
    Ismael

  3. Ismael Juma says:

    Oh well, seems like I was too slow. 🙂

    Ismael

  4. You are absolutely right on this. I’ve wasted countless hours on broken assumptions such as “this exception never happens”.

    On the other hand, the standard Java library is full of inappropriate use of Exceptions that you might strongly argue actually don’t happen or only happen if you fail to do some elementary checking on your data. A run time exception is much more appropriate in such cases.

    For example, I’ve encountered many times that I have to catch a UnsupportedEncodingException exception while I am pretty sure that a lack of support for utf-8 is pretty rare. So my code reads setEncoding(“utf-8”); and I am forced to deal with the possibility that utf-8 is somehow not supported.

    I always log this type of exception at severe level because if it does happen something is seriously wrong with my code (e.g. typo in the utf-8). But it’s tedious to have to write this code.

  5. Throughly excellent blog and couldn’t agree more. I not only see students doing this, but many academics actually teaching with code that does this. It’s pure evil!

    The usual shorthand I use when there is no appropriate constructor is:

    throw new InternalError(msg).initCause()

    as initCause returns the original throwable. You may need to cast as well to get the right exception for the throws statement. Someone could really do with adding the appropriate constructors to all the API ones though; does this really need a JSR?

    The message also annoys me as so many times people don’t include state information that would much cut down the debugging time e.g. “Invalid format” or “Incorrect pattern” — why not include the format or pattern in the string as well?!?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: