Copyright © 2004 O'Reilly Media, Inc. All Rights Reserved.
Essential ActionScript 2.0
By Colin Moock
June 2004
ISBN: 0-596-00652-7
More info... .
Available from booksellers or direct from O'Reilly Media, www.oreilly.com.

Cover image
This content is excerpted from the above-named O'Reilly publication, with permission, by agreement with ActionScript.org.

Should you define an Error subclass for each error condition? Typically, no, you won't need that level of granularity because in many cases multiple error conditions can be treated in the same way. If you don't need to differentiate among multiple error conditions, you can group them together under a single custom Error subclass. For example, you might define a single Error subclass named InvalidInputException to handle a wide range of input problems.

That said, you should define a separate Error subclass for each error condition that you want to distinguish from other possible conditions. To help you understand when you should create a new subclass for a given error condition and to demonstrate how to group multiple conditions into a single subclass, let's return to our familiar Box class.

Earlier we generated three exceptions from the Box.setWidth( ) method: one for general invalid data, one for too small a width, and one for too large a width. All three Box-related exceptions used the generic Error class. Here's the code again:

public function setWidth (w:Number):Void {
if (isNaN(w) || w == null) {
throw new Error("Illegal Box dimension specified.");
} else if (w <= 0) {
throw new Error("Box dimensions must be greater than 0.");
} else if (w > Number.MAX_VALUE) {
throw new Error("Box dimensions must be less than Number.MAX_VALUE.");
}
width = w;
}

In the preceding code, to differentiate Box exceptions from all other exceptions in our application, we use the Error class's message property, which, as we just learned, made our exceptions awkward to use and prone to human error. A better way to set Box-related data errors apart from other errors in our application is to define a custom Error subclass, BoxDimensionException, as follows:

// Code in BoxDimensionException.as:
class BoxDimensionException extends Error {
public var message:String = "Illegal Box dimension specified.";
}

With our BoxDimensionException class in place, our Box.setWidth( ) method can throw its very own type of error, as follows:

public function setWidth (w:Number):Void {
if (isNaN(w) || w == null) {
// Throw a BoxDimensionException instead of an Error.
throw new BoxDimensionException( );
} else if (w <= 0) {
throw new BoxDimensionException( );
} else if (w > Number.MAX_VALUE) {
throw new BoxDimensionException( );
}
width = w;
}

Notice that the preceding method definition throws the same error type (BoxDimensionException) for all three Box-related error conditions. As developers of the Box class, we now face the crux of the error granularity issue. We must decide not only how distinguishable we want Box error messages to be from other application errors, but also how distinguishable we want those errors to be from one another. We have the following options:

Option 1: use a single Box error class.

Leave the preceding setWidth( ) method definition as-is. As we'll see shortly, this option lets us distinguish Box errors from other generic errors in the program, but it does not help us distinguish internally among the three varieties of Box-related errors (invalid data, too small a width, and too large a width).

Option 2: simplify code, but still use a single Box error class.

Refactor the setWidth( ) method to check for all three error conditions using a single if statement. This option is the same as the previous option, but uses cleaner code.

Option 3: use debugging messages to distinguish among errors.

Add configurable debugging messages to the BoxDimensionException class. This option adds slightly more granularity than the previous two options but only for the sake of the developer and only during debugging.

Option 4: create a custom exception class for each error condition.

Create two custom BoxDimensionException subclasses, BoxUnderZeroException and BoxOverflowException. This option provides the most granularity—it lets a program respond independently to the three varieties of Box-related errors using formal branching logic.

Let's consider the preceding options in turn.