The Artima Developer Community
Sponsored Link

Angle Brackets and Curly Braces
What's Your ShouldNeverHappenException?
by Bill Venners
January 16, 2007
Summary
Java's checked exceptions sometimes force you to catch a checked exception that you believe will never be thrown. Best practice dictates that you wrap that in an unchecked exception and rethrow it, just in case. What exception class do you wrap with in that case?

Advertisement

In my Failure Happens: Deal with It! talk, which I gave last month at JavaPolis, I described a situation I encounter fairly regularly as a Java programmer. The compiler forces me to catch a checked exception that I believe will in all likelihood never be thrown. For example, in our web application that runs Artima, we always encode URLs with UTF-8 encoding by passing "UTF-8" to java.net.URLEncoder.encode(). Here's an example:

private static final String UTF8_CHAR_ENCODING = "UTF-8";

// ...

    String encodedURL;
    try {
        encodedURL = URLEncoder.encode(url, UTF8_CHAR_ENCODING);
    }
    catch (UnsupportedEncodingException e) {
        // Should never happen
        throw new RuntimeException(e);
    }

// ...

It is my belief that "UTF-8" will always be supported as a character encoding, so I expect that UnsupportedEncodingException will never be thrown. But since UnsupportedEncodingException is checked, I must either catch it or declare it in the calling method's throws clause.

What I recommend in my talk is be sure and not simply swallow such exceptions, even though you think they will never happen, because someday they just might. Better to wrap them in a runtime exception that will result in a killed thread and a stack trace if they're ever actually thrown. I always put the comment, "// Should never happen", in such cases, and I programmed my IDE to generate such code by default when it generates catch clauses.

The feedback I got from the audience was that this is all well and good, but some would have wrapped the exception in an AssertionError instead of a plain old RuntimeException, because that is semantically more accurate. One reason I wrap it in RuntimeException is that in our web application, we have a last ditch catch clause that catches any uncaught Exceptions and prints out information to a log file that can be helpful in debugging. After printing the information, this last ditch catch clause exits normally (it doesn't rethrow any exception). Therefore, the app server knows nothing of an exception and happily and quietly returns the thread to its thread pool.

I want that information to be printed if a "should never happen" exception ever gets thrown. I could easily factor out the code that logs the information into a method called by two catch clauses, one for Exception and the other for AssertionError. Perhaps I should do that anyway in case some programmer we hire actually uses asserts, which Frank Sommers and I tend not to use. I don't catch Throwable, because in general Errors I figure I should let propagate out, allowing the app server to deal with them as it sees fit. Given that these exceptions really should never happen, I think the main concern should be how obvious is it to readers that a catch clause is a "should never happen" case. AssertionError may indicate that better than RuntimeException, but the comment "// Should never happen" I think makes it pretty clear.

What's your opinion? What exception would you wrap with in the "// Should never happen" case?

Talk Back!

Have an opinion? Readers have already posted 73 comments about this weblog entry. Why not add yours?

RSS Feed

If you'd like to be notified whenever Bill Venners adds a new entry to his weblog, subscribe to his RSS feed.

About the Blogger

Bill Venners is president of Artima, Inc., publisher of Artima Developer (www.artima.com). He is author of the book, Inside the Java Virtual Machine, a programmer-oriented survey of the Java platform's architecture and internals. His popular columns in JavaWorld magazine covered Java internals, object-oriented design, and Jini. Active in the Jini Community since its inception, Bill led the Jini Community's ServiceUI project, whose ServiceUI API became the de facto standard way to associate user interfaces to Jini services. Bill is also the lead developer and designer of ScalaTest, an open source testing tool for Scala and Java developers, and coauthor with Martin Odersky and Lex Spoon of the book, Programming in Scala.

This weblog entry is Copyright © 2007 Bill Venners. All rights reserved.

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use