Exception handling in Java

December 17, 2007

On every project I’ve worked on, one of the first things I have to do is work out why an exception was thrown. Usually, that first error message doesn’t contain enough information to help me solve the problem. At this point I congratulate the previous developer of the system on getting so far with such sloppy error handling.

After congratulating myself, I move on to reviewing the project’s approach to exception handling. I like to do this globally if possible, to ensure that the approach is consistent throughout the project, and so that I can have reasonably expect to see the information I need next time something goes wrong.

Good exception handling and reporting is critical to the success of any software project. Since the bulk of a project’s lifetime is spent in bug fixing and maintenance, good error reporting can make this phase of a project much less time consuming that it might be. With a stack trace, I can immediately tell where the fault occurred, and who was calling that code. In most cases, that’s enough information to understand the problem.

I’ve completely refactored the exception handling of a couple of medium-sized projects; in doing so, I’ve observed a few rules of thumb make this process a breeze if followed. I’ll try to summarize them here:

Don’t swallow nested exceptions

Change this:

    try { ... }
    catch (Foo e) { throw Bar() }

to this:

    try { ... }
    catch (Foo e) { throw Bar(e) }

The first exception thrown is always the most important for software developer; it provides information about the underlying cause and location of a failure. When you discard it this way, determining what happened is next to impossible.

In case you’re wondering, the following is not a good substitute:

    try { ... }
    catch (Foo e) { throw Bar(e.getMessage()) }

Tempting, but count yourself lucky if you get any useful information this way; you’ll probably get a vague message, or perhaps nothing at all. And you just lost the most useful piece of information: the stack trace of the underlying error.

Read the rest of this entry »