Rogue Wave banner
Previous fileTop of DocumentContentsIndex pageNext file
Essential Tools Module User's Guide

10.2 Error Categories

In the Essential Tools Module model, errors are divided into two broad categories: internal and external. (A third category also exists: stream buffer allocation errors. The Rogue Wave public interface does include a class to handle these errors, although they are far less common and are not discussed in detail here.)

Internal errors, which are further classified as either recoverable or non-recoverable, are due to errors in the internal logic of the program. As you might expect, they can be difficult to recover from and, indeed, the common default response is to abort the program. External errors are due to events beyond the scope of the program. Any non-trivial program should be prepared to recover from an external error.

10.2.1 The Essential Tools Module Error Model

The following table describes errors in the Essential Tools Module error model.

Table 21: Error Types in the Essential Tools Module 

Error Types: Internal Non-recoverable Internal Recoverable External
Cause:

Faulty logic or coding in the program

Faulty logic or coding in the program

Events beyond the scope of the program

Examples:

Bounds error; inserting a null pointer into 0a collection

Bounds error in a linked list; attempt to use an invalid date

Attempts to write a bad date, or to invert a singular matrix; stream write error; out of memory

Predictable?

Yes

Yes

No

Cost to detect:

High

Low

Low

Level of abstraction:

Low

Low

High

Where detected:

Debug version of library

Debug and production version of library

Debug and production version of library

Response:

No recovery mechanism

Throws an exception inheriting from RWInternalErr

Throws an exception inheriting from RWExternalErr, or provide test for object validity

10.2.2 Internal Errors

Internal errors are due to faulty logic or coding in the program. Common types of internal errors include:

All these errors should be preventable. For example, you always know the permissible range of indices for an array, so you can probably avoid a bounds error. You would correct your program's use of a bad date as an obvious logic error.

Internal errors can be further classified according to the cost of error detection, and whether or not the error will be detected at run time. The two categories are:

10.2.2.1 Non-recoverable Internal Errors

Non-recoverable internal errors share the following distinguishing characteristics. They are:

Non-recoverable internal errors by definition have no recovery mechanism. Examples of these errors include bounds errors and inserting a null pointer into a collection.

A library defines some errors unrecoverable because detecting errors takes time. For performance reasons, a library demands a minimal level of accuracy and rejects any part of your program that falls short. Errors are non-recoverable in the sense that the production version of the library has no mechanism for detecting such errors. This means there is no opportunity to recover from them.

Bounds errors are non-recoverable because the cost of checking that an index is in range can well exceed the cost of the array access itself. If a program does a lot of array accesses, checking every one may result in a slow program. To avoid this, the library may require you to always use a valid index. Because a minimum level of accuracy is demanded, non-recoverable errors are simple in concept and relatively easy to avoid.

You can best discover and eliminate non-recoverable errors by compiling and linking your application with the debug version of the library. See Section 10.4 in this chapter for details. The debug version includes extra checks designed to uncover coding errors. Some of these checks may take extra time, or even cause debug messages to be printed. For this reason, you will want to compile and link with the production version for an efficient final product. If the debug version of the library discovers an error, it typically aborts the program.

10.2.2.2 Recoverable Internal Errors

Recoverable internal errors are similar to their non-recoverable relatives because they are easy to predict and occur at low levels.

They differ in that they are

A bounds error in a linked list or an attempt to use an invalid date are both examples of recoverable internal errors. The library's response to these errors is to throw an exception inheriting from RWInternalErr, using the macro RWTHROW.

The production version of the library can check for recoverable internal errors because the cost is relatively low. For example, to find a bounds error in a linked list, the cost of walking the list far exceeds the cost of detecting whether the index is in bounds. Hence, you can afford to check for a bounds error on every access.

If an error is discovered, the library throws an exception inheriting from RWInternalErr, as we have mentioned. Following is an example:

In this code, note how the function always attempts to detect a bounds error. If it finds one, it throws an instance of RWBoundsErr, a class that inherits from RWInternalErr. This instance contains an internationalized message, discussed in Section 8.3, "Localizing Messages."

Throwing an exception gives you the opportunity to catch and possibly recover the exception. However, because the internal logic of the program has been compromised, you should attempt to save the document you are working on, and abort the program.

10.2.3 External Errors

External errors are due to events beyond the scope of the program. As we mentioned in the introduction, any non-trivial program should be prepared to recover from an external error. In general, external errors are:

Examples of external errors include: an attempt to set a bad date, such as 31 June 1992; an attempt to invert a singular matrix; a stream write error; being out of memory. The Essential Tools Module responds by throwing an exception inheriting from RWExternalErr, or providing a test for object validity.

External errors may be run time errors. In an object-oriented environment, run time errors frequently result from an attempt to set an object into an invalid state, perhaps as a result of invalid user input. The example given above, initializing a date object with the nonexistent date 31 June 1992, is an external run time error.

External errors often take the form of exceptions thrown by the operating system. The Essential Tools Module takes responsibility for detecting these exceptions and recovering the resources it has acquired; it will close files and restore heap memory. As the user, however, you are responsible for all resources acquired by code external to the Essential Tools Module library during these kinds of exceptions. Generally, the Essential Tools Module assumes that these exceptions will not be thrown during memory-related C library calls such as memcpy. The Essential Tools Module make every effort to detect throws which occur during operations on the Essential Tools Module objects or user-defined objects.

In theory, the Essential Tools Module's response to an external error is to throw an exception, or to provide a test for object validity. It should never abort the program. In practice, however, some compilers do not handle exceptions, so the Essential Tools Module provides an opportunity to recover in an error handler, or to test for a status value. Here is an example of using the isValid function to validate user input:



Previous fileTop of DocumentContentsIndex pageNext file

©2004 Copyright Quovadx, Inc. All Rights Reserved.
Rogue Wave and SourcePro are registered trademarks of Quovadx, Inc. in the United States and other countries. All other trademarks are the property of their respective owners.
Contact Rogue Wave about documentation or support issues.