qrcode
The slightly less long-winded not-at-work version of Will

Theme by nostrich.

29th May 2011

Post

Checked vs. Unchecked Exceptions: ONE Story

First, here’s the thread on Twitter:

@willathome: Writing a Java API from scratch - checked or unchecked exceptions?
@robhines: @willathome I vote Checked!
@willathome: @robhines there are good reasons for checked - most notably that they’re documented. But it’s inconsistent with PHP, .NET, etc.
@robhines: @willathome I think it is best to leverage the language, checked forces better client programming IMHO. Would be nice for other languages.
@willathome: @robhines now there’s a thought - rather than writing to the least common denominator, use all the strengths available in each.
@willathome: @robhines to further prove your point - if I wanted to be consistent with C, I’d not use exceptions at all. 0 for success non-0 for failure.
@jon_peterson: @willathome I could go for hours on this. Short answer “both”. I’m with the moderate Rod Johnson on this one. Eckel is too extreme for me.
@willathome: @jon_peterson I’ve honestly thought about duplicating API’s in the past to give clients the option.
@jon_peterson: @willathome I like check exceptions when used correctly, but hate them when they are used stupidly. Here is a good read
@robhines: @willathome So, checked or unchecked? What are the arguments you have for unchecked so far?
@robhines: @willathome if you had asked @Jinksto he would have told you not to write it in Java to begin w/and avoid the question altogether. :-)
@willathome: Thanks all for the insight on whether to use checked or unchecked. Will write a blog post on the decision and process.

So that was the Twitter feed.

The idea was that I was writing a client API to a REST service using Java. When a client is communicating with a REST service, there are a lot of things that can go sideways.

If you’re not familiar, Java has the concept of checked exceptions. In fact, most exceptions are checked. Very few languages with exceptions have checked exceptions. Catching a checked exception is enforced by the compiler - so if you call a method that throws a checked exception, you must either catch that exception, or declare in your method definition that you throw that exception, or the code won’t compile. Most exceptions in Java are checked. Only subclasses of RuntimeException or Error are unchecked - meaning, if you call a method which throws RuntimeException or Error or a subclass of those, then you’re not required to explicitly catch or re-throw that exception. If nothing catches an unchecked exception, the runtime will catch it and terminate.

The debate over checked vs. unchecked exceptions goes way, way back. Some say it’s one of the best features Java included. Others say it was one of their biggest mistakes. I wasn’t hoping to resolve it in one night, but wanted to know how to handle my API. And I probably didn’t give enough information. But thanks to the folks who did pipe in.

While @robhines gave some very valuable points for using checked exceptions, I ultimately decided for unchecked exceptions, but not for the reasons traditionally stated.

In this particular case, it made sense because of how I expected people to use this API. Writing a client for a REST service in Java is not terribly, terribly difficult. However, as I mentioned, there are a lot of things that can go wrong. This particular API I was writing, I intend for folks to generally use in short scripts or in simple CLI tools for getting the work done. In 99% of those cases, the code itself won’t be able to recover from problems in the API. Yes, they could do some robust error checking for things like authentication failures and re-prompt the user for credentials, however, I expect users of this particular API will be writing automation scripts that won’t prompt for credentials at all. And using unchecked exceptions doesn’t preclude people being able to catch those exceptions.

Basically, using unchecked exceptions, people will likely do this:

public static void main(String[] args) {
  callApi1();
  calApi2();
}

with unchecked exceptions, if anything goes wrong, the app will basically vomit all over itself.

If I were using checked exceptions, people would look for the shortest possible path to let the code vomit all over itself - namely:

public static void main(String[] args) throws Exception {
  callApi1();
  callApi2();
}

Writing the API to use unchecked exceptions actually took a lot of time on my part, however. As I mentioned, with a REST API, there are lots of things that can go wrong, most of which either throw checked exceptions or use HTTP status codes. So I had to explicitly catch all the specific checked exceptions, carefully re-thowing those as unchecked exceptions, and explicitly document all the unchecked exceptions my code might throw.

So that’s not the be-all-end-all answer you were probably looking for if you read this far, but that was my decision process for this particular API - opted for unchecked because I expect most people will use this API for throwaway headless CLI scripts, and using unchecked exceptions doesn’t preclude them handling exceptions more elegantly.

by

()