Wizard API updated!
Tim Boudreau has released a new version of the Swing Wizard library (version 0.997) that fixes the WizardException bug reported in JavaWorld's recent Open Source Java Project profile. The article's examples have been reworked to test out the new, improved WizardException. Thanks, Tim, for this helpful fix!
Open Source Java Projects: The Wizard API

Newsletter sign-up

Sign up for our technology specific newsletters.

Enterprise Java
View all newsletters

Email Address:

Beware the dangers of generic Exceptions

Catching and throwing generic Exceptions can get you into trouble quickly and quietly

While working on a recent project, I found a piece of code that performed resource cleanup. Because it had many diverse calls, it could potentially throw six different exceptions. The original programmer, in an attempt to simplify the code (or just save typing), declared that the method throws Exception rather than the six different exceptions that could be thrown. This forced the calling code to be wrapped in a try/catch block that caught Exception. The programmer decided that because the code was for cleanup purposes, the failure cases weren't important, so the catch block remained empty as the system shut down anyway.

Obviously, these aren't the best programming practices, but nothing seems to be terribly wrong...except for a small logic problem in the original code's third line:

Listing 1. Original cleanup code

private void cleanupConnections() throws ExceptionOne, ExceptionTwo {
   for (int i = 0; i < connections.length; i++) {
      connection[i].release(); // Throws ExceptionOne, ExceptionTwo
      connection[i] = null;
   }
   connections = null;
}
protected abstract void cleanupFiles() throws ExceptionThree, ExceptionFour;
protected abstract void removeListeners() throws ExceptionFive, ExceptionSix;
public void cleanupEverything() throws Exception {
   cleanupConnections();
   cleanupFiles();
   removeListeners();
}
public void done() {
   try {
      doStuff();
      cleanupEverything();
      doMoreStuff();
   }
   catch (Exception e) {}
}


In another part of the code, the connections array is not initialized until the first connection is created. But if a connection is never created, then the connections array is null. So in some cases, the call to connections[i].release() results in a NullPointerException. This is a relatively easy problem to fix. Simply add a check for connections != null.

However, the exception is never reported. It is thrown by cleanupConnections(), thrown again by cleanupEverything(), and finally caught in done(). The done() method doesn't do anything with the exception, it doesn't even log it. And because cleanupEverything() is only called through done(), the exception is never seen. So the code never gets fixed.

Thus, in the failure scenario, the cleanupFiles() and removeListeners() methods are never called (so their resources never release), and doMoreStuff() is never called, thus, the final processing in done() never completes. To make matters worse, done() is not called when the system shuts down; instead it is called to complete every transaction. So resources leak in every transaction.

This problem is clearly a major one: errors are not reported and resources leak. But the code itself seems pretty innocent, and, from the way the code was written, this problem proves difficult to trace. However, by applying a few simple guidelines, the problem can be found and fixed:

  • Don't ignore exceptions
  • Don't catch generic Exceptions
  • Don't throw generic Exceptions


Don't ignore exceptions

The most obvious problem with Listing 1's code is that an error in the program is being completely ignored. An unexpected exception (exceptions, by their nature, are unexpected) is being thrown, and the code isn't prepared to deal with that exception. The exception isn't even reported because the code assumes the expected exceptions will have no consequences.

1 | 2 | 3 | 4 | 5 |  Next >

Discuss

Start a new discussion or jump into one of the threads below:

Subject Replies Last post
. What are you actually handling?
By Anonymous
9 10/29/06 06:35 AM
by Anonymous
. Checked/Unchecked distinction now blurred
By matthew_ford
6 10/29/06 05:50 AM
by Anonymous
. Proposed guidelines miss the mark
By Jay Dunning
( Pages 1 2 all )
20 10/29/06 05:50 AM
by Anonymous
. Not convinced
By Anonymous
3 10/29/06 02:18 AM
by Anonymous
. Author fails to address GUI's
By Anonymous
5 10/29/06 02:06 AM
by Anonymous
. The alternative to catch all
By Daniel Santos
3 10/29/06 12:07 AM
by Anonymous
. Throwing and catching RunTimeExceptions
By Mayur Purandar
2 10/28/06 08:46 PM
by Anonymous
. A cleaner Approach for Multiple Exceptions
By Krishna Balwalli
9 10/04/06 05:58 AM
by Anonymous
. Exceptions
By Anonymous
1 10/03/06 11:45 AM
by Anonymous


Resources