Expection handling explained

Expection handling is a computer programming anti-pattern. It refers to using a computer language's error handling structures to perform normal program logic, like control flow. The term comes from combining exception handling with the word expect: In other words, expection handling is catching occurrences that you expect to happen.

Hazards

The expection handling anti-pattern can cause a number of problems:

Examples

The "reference implementation" of expection handling is blindly stepping through a collection, and catching an error when you go beyond the bounds of that collection.

java


try
{
    int idx = 0;
    while (true)
    {
        displayProductInfo(prodnums[idx]);
        idx++;
    }
}
catch (IndexOutOfBoundsException ex)
{
    // nil
}

Another example of expection handling would be using an exception to signal that an operation completed successfully:

java

public void saveData(OutputStream os) throws SuccessException, IOException
{
    PrintStream ps = new PrintStream(os);
    ps.print(this.data);
    ps.flush;
    throw new SuccessException("Data saved successfully");
}

In this case, any code using the saveData function will be forced to deal not only with any input-output problem signaled by IOException, but also with the "error" signaled by SuccessException, which is, however, supposed to be part of the program's normal operation. Exceptions are only meant to signal about abnormal situations, and should not be used to merely pass information.

When expection handling is not an anti-pattern

In unit testing, it becomes necessary to verify that the code correctly throws exceptions in situations when it is supposed to. For example, when testing a collection, the tests can verify that the class indeed throws an IndexOutOfBoundsException when an invalid index is passed.

JUnit version 4 includes support for expection handling via the expected parameter of the @Test annotation, which considers the test failed if the exception specified in it is not thrown. Using JUnit 4, a simple test for ArrayList's behavior out of bounds can be written like this:

java

@Test(expected= IndexOutOfBoundsException.class)
public void testOutOfBounds
{ 
    new ArrayList<Object>.get(0); 
}

Before JUnit added support for the expected notation, the code had to be written as follows:

java


public void testOutOfBounds
{
    try { 
        new ArrayList<Object>.get(0);
        fail("Expected IndexOutOfBoundsException");
    }
    catch(IndexOutOfBoundsException expected) {}
}