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:
*Not easily predicted in advance
*Encountered at more abstract levels
*Not costly to detect
*Detected in both the production and the debug versions of the library
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:
 
RWDateTime date;
while (1) {
cout << "Give a date: ";
cin >> date;
if (date.isValid()) break;
cout << "You entered a bad date; try again\n";
}