An important characteristic of quality software is its abil-ity to handle errors that arise in processing (also called run-time errors or “exceptions”). Before it is released for general use, a program should be thoroughly tested with a variety of input (see quality assurance, software). When errors are found, the soundness of the algorithm and its implementation must be checked, as well as the program logic (see algorithm). Interaction between the program and other programs (including the operating system) as well as with hardware must also be considered. (See bugs and debugging.)
However, even well-tested software is likely to encoun-ter errors. Therefore a program intended for widespread use must include instructions for dealing with errors, antici-pated or otherwise. The process of error handling can be divided into four stages: validation, detection, communica-tion, and amelioration.
Data validation is the first line of defense. At the “front end” of the program, data being entered by a user (or read from a disk file or communications link) is checked to see whether it falls within the prescribed parameters. (In the case of a program such as a data management system, the user interface plays an important role. Data input fields can be designed so that they accept only valid characters. On-line help and error messages can explain to users why a particular input is invalid.)
However, data validation can ensure only that data falls within the generally acceptable parameters. Some particu-lar combination or context of data might still be erroneous, and calculations performed within the program can also produce errors. Some examples include a divisor becoming zero (not allowable mathematically) or a number overflow-ing or underflowing (becoming too large or too small for register or memory space allotted for it).
Error communication is generally handled by a set of error codes (special numeric values) returned to the main program by the function used to perform the calculation. In addition, errors that arise in file processing (such as “file not found”) also return error codes. For example, suppose there is a division function in C++
double Quotient(double dividend, double divisor) throw(ZERODIV)
{
if (0.0 == divisor) throw ZERODIV();
return dividend / divisor;
}
In C++ “throw” means to post an error that can be “caught” by the appropriate error-handling routine. Thus, the corresponding “catch” code might have:
catch( ZERODIV )
{
cout << “Division by zero error!” << endl;
}
Once an error has been detected and communicated, decision statements (branches or loops) can check for the presence of error codes and execute appropriate instruc-tions based on what is encountered. (In object-oriented lan-guages such as C++ special classes and objects are often used to handle errors.)
Many simple utility programs respond to errors by issu-ing an error message and then quitting. However, many real-world applications must be able to respond to errors and continue processing (for example, a program reading data from a scientific instrument may have to deal with the occasional “outlier” or a strange value caused by a burst of interference). Depending on circumstances, the error ame-lioration code might simply reject the erroneous data or result, ask for the data to be re-sent, or keep a log or statis-tics of the number and kind of errors encountered. More sophisticated approaches based on mathematical error analysis are also possible.
No comments:
Post a Comment