Atom Feed SITE FEED   ADD TO GOOGLE READER

Catching unchecked exceptions is fragile

In my project we're having a great discussion about whether to use checked or unchecked exceptions for a particular problem. I've discovered an interesting problem with unchecked exceptions - they're not as robust with respect to refactoring and maintenance.

Here's some code that gracefully handles the unchecked exception called MappingServiceUnreachableException:
  /** 
* @return the directions, or {@code null} if they are unavailable.
*/
public Directions tryToLookupDirections(Address from, Address to) {
try {
MappingSession session = mappingService.openSession();
MappingResponse response = session.request(
new DirectionLookupRequest(from, to));
} catch(MappingServiceUnreachableException e) {
logger.log(Level.WARNING, e.getMessage(), e);
return null;
}
}
The code passes all unit tests written for it. It gets checked in and gets QA testing. But a few weeks later, I discover a performance problem from not closing the session. This is an easy fix:
  /** 
* @return the directions, or {@code null} if they are unavailable.
*/
public Directions tryToLookupDirections(Address from, Address to) {
MappingSession session = mappingService.openSession();
try {
MappingResponse response = session.request(
new DirectionLookupRequest(from, to));
} catch(MappingServiceUnreachableException e) {
logger.log(Level.WARNING, e.getMessage(), e);
return null;
} finally {
session.close();
}
}
In order to have a reference to MappingService in the finally block, I moved the call to openSession() outside of the try block. I've inadvertently changed the behaviour when that method throws!

When do find out about my mistake?
  • If MappingServiceUnreachableException was a checked exception, I'd find out about my blunder as I make it. If I'm using a good IDE, I find out before I even save the file.

  • If I have complete test coverage for the exceptional case, I'll find out about my blunder the next time that test is run - probably within a few minutes.

  • If I have only sunny-case test coverage, I won't find out about my blunder until the next time that the mapping service is unavailable.


I prefer fail-fast, so in this case checked exceptions are a no brainer. They're not perfect everywhere, but they certainly serve their purpose.
An interesting point. While checked exceptions and type safety are often berated for being unnecessary and verbose, in the context of maintenance and collaboration however the arguments against them can often wear thin.

I guess it is always easy to put maintenance on the back burner when your immediate task is the challenge of implementation.