magpiebrain

Sam Newman's site, a Consultant at ThoughtWorks

I like unchecked exceptions. Here’s why – I like to know something went wrong without having to explicitly handle every possible error. I like checked exceptions. Here’s why – when I decide that an error should be handled in my system, I want to force it to be handled as a defensive measure. We can argue back and forth about the merits of checked exceptions – Java chose it’s path, .NET another, some people don’t like exceptions at all – but that is a discussion for another place. What I want to look at is how these two types of exception get used on our current project.

As I mentioned before, we’re using unchecked exceptions for error conditions we cannot handle, and checked exceptions we can handle. Unchecked exceptions are allowed to bubble up to the top level, where they are logged.

Checked exceptions are never logged and rethrown – if we had to rethrow the exception because we cannot properly handle it, it means it really should be unchecked, and we should allow the top level to catch and log it. For example we don’t have examples of the following code in our code base:



	

public void doSomething() {

try { doSomeOtherMethod(); } catch (SomeCheckedException e) { log(e); throw new UncheckedException(e); } }

Instead, if we can’t handle doSomeOtherMethod’s exception, it should be unchecked and we should rely on the top-level to catch and log it:



	

public void doSomething() {

... doSomeOtherMethod(); .. }

If we can handle the error generated by doSomeOtherMethod, then the code should be more clearly written as:



	

public void doSomething() {

try { doSomeOtherMethod(); } catch (SomeCheckedException e) { log("Error occurred, but we'll handle it<a href="http://www.magpiebrain.com/archives/2003/11/21/proper_exception_handling" <5>>, e); handleErrorState(e); } }

We’ve handled it immediately, in place, and haven’t propagated any exceptions.

There are of course exceptions to this rule (no pun intended). In the case of third party API’s, we may find that the exceptions they throw don’t match the context in which we are using them. Our JMS-based system assumes messages will be Java objects (de)serialized using XStream and sent as XML. The XStream code is pretty simple:



	

XStream xstream = new XStream(); Object anObject = xstream.fromXML(xmlToDeserialize);

XStream throws unchecked exceptions only – not that you could work that out from the Javadoc (I’m all in favour of lightly documented code, but external API’s should really document the unchecked exceptions they can explicitly throw). For us, we want to be able to handle the fact we gave our deserializer some dodgy XML – which implies we need a checked exception. To handle this, we explicitly catch the StreamException, but not Throwable:



	

XStream xstream = new XStream(); try {

Object anObject = xstream.fromXML(xmlToDeserialize); } catch(StreamException e) { throw new DeserializerException(e); }

The reason we don’t catch all exceptions, is that we are happy we can handle the outcome if a StreamException can be thrown – we understand that scenario. If XStream started throwing NullPointerException’s however, it’s a brand new scenario we haven’t planned for – we have to assume we can’t handle that one. Put another way, what if we were using a new version of the XStream library that had a bug in it? By assuming any unchecked exception thrown by XStream was down to bad XML, we could end up throwing away lots of valid data.

and Catching uncaught exceptions )

Ian Griffiths has a similar take on exception handling, with more emphasis on application tiers/layers. Also note that I don’t claim that I as a person (or the development team as a whole) came up with this approach – as Ian’s post shows there is bound to be plenty of prior art out there 🙂

Advertisements

2 Responses to “Exception handling revisited”

  1. Tim

    Hey Sam, aren’t you making assumptions about what the caller can and cannot handle within the throwing class? I mean, why does the pitcher care what the catcher can handle? What if you get a new catcher that can’t handle your checked exceptions or someone who can handle your runtime exceptions?

    Is there a good rule of thumb for knowing when your caller should be able to handle an exception and when to throw an unchecked exception?

    Reply
  2. sam newman

    Yes, you are maing that assumption – and that is one of the problems I had with this approach, especially if you aren’t the person whose going to be doing the calling.

    The way I think of it, is that I use checked exceptions within an application statck, but never throw a checked exception out of the boundry of the application. I have complete control over the stack, therefore know what error conditions can be handled. It’s not a one-size fits all approach however – for example what happens if you call the same class in two different contexts? In one you can handle the error, in the other you can’t. That said for 99% of code, exception handling has become a no-brainer, and has resulted in simpler, cleaner error handling.

    Reply

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

Basic HTML is allowed. Your email address will not be published.

Subscribe to this comment feed via RSS

%d bloggers like this: