When to Catch, Pass, or Throw Exceptions?

by

Rule 1. When to Catch an Exception

Catch an exception if you can solve the problem raised by the exception (e.g. by waiting for system resources, balking on a client request in an orderly fashion, interrupting a thread, logging the problem and continuing, or freeing memory).

Rule 2. When to Throw an Exception

Throw an exception with an appropriately specific type when a problem arises that you can’t solve.

Runtime exceptions  are for programming errors (e.g. null pointers,index out of bounds, or illegal arguments).

Errors  are for system resource errors (e.g. out of memory).

Checked exceptions  are for predictable forms of application-specific errors (e.g. ill-formed input for parsers, busy network resources, or file permissions).

Corollary 3. When to Pass an Exception

Pass any exception that is raised that you don’t want to catch.

Pass the exception as-is if possible. This requires no code, but for checked exceptions, requires an appropriate try/catch block or a method/constructor declared to throw the exception.

If the exception may not be passed as is, use a try/catch to catch it and throw a new reasonably typed exception that wraps the adapted exception. That is, don’t just throw an instance of RuntimeException, which is neither an error nor specific enough for a client to catch.

3 Responses to “When to Catch, Pass, or Throw Exceptions?”

  1. João Says:

    Great post!

    I tend to disagree with Rule 1. Consider, for example, a loop where a query is being issued to a different search engine in each iteration, and the results are being accumulated. In this situation, if one of the search engines doesn’t respond, you probably just want to log the error and proceed with the loop, even though the “problem raised by the exception” was not solved per se.

    With respect to Rule 2, I agree on all counts except Runtime/unchecked exceptions. I think unchecked exceptions should be thrown not only for programming errors, but also for situations where the client can’t recover/proceed from the exception. An example, which I came across a few weeks ago, was an application that was required to load a great deal of resources at startup, and couldn’t proceed without any of them. The solution was to create an unchecked exception ResourceNotFoundException.

    What are your thoughts on these?

    • Thomas Yee Says:

      João wrote:
      >I tend to disagree with Rule 1. Consider, for example, a loop where a
      >query is being issued to a different search engine in each iteration, and
      >the results are being accumulated. In this situation, if one of the search
      >engines doesn’t respond, you probably just want to log the error and
      >proceed with the loop, even though the “problem raised by the
      >exception” was not solved per se.

      But that IS following Rule 1! In your particular case, it is a high-level recognition of the fact that dead links and/or downed servers is a fact of life on the web, and logging the error and proceeding with the loop indeed represents an appropriate action that “solves the problem raised by the exception”.

  2. lingpipe Says:

    I updated the post to reflect that I meant to include logging errors and continuing as a way to handle exceptions. The point is that the catcher here is doing this explicitly at an appropriate point in the loop. The wrong way to do this is to have some deeply nested component swallow an exception, then proceed until the next item either gets into an illegal state or throws a null pointer exception or whatever.

    I tend to think of resources not being found as programming exceptions, though I suppose they show up in J2EE settings very much like other network errors. I often throw illegal argument exceptions if I can’t construct an object with the arguments given, but something more specific like resource-not-found exceptions would be even better.

    I think you might be surprised what enterprising clients can recover from. Sometimes there are alternative lower-resource configurations available. For instance, LingPipe can trade model size for accuracy in most situations.

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