FAQ 26.03 Should a catch block fully recover from an error?

FAQ 26.03 Should a catch block fully recover from an error?

graphics/new_icon.gif

If possible. But sometimes the best that can be done is some cleanup and a rethrow.

If a function can completely recover from the error, then it can either continue with normal processing or restart the try block (put the try block in a loop, for example).

If a function can affect a partial, local recovery from the error, the catch clause can propagate the exception to the calling function either by throwing the same exception object (throw;) or by throwing a different exception object.

The worst thing to do is to leave the system in an ill-defined state by affecting a partial, local recovery from the error and then returning to normal processing. Here is an example of acceptable ways to handle the problem.

The first step is to define some exception classes. For this example, two exception classes are needed: BadFileName for file names that are invalid and AccessViolation for file names that are valid but which refer to files that cannot be accessed by the current user (for example, insufficient privileges). Since all exception classes should inherit from a very small number of base classes (see FAQ 9.10), these exception classes inherit from the standard exception class runtime_error:

 #include <stdexcept> #include <iostream> #include <string> using namespace std; class BadFileName : public runtime_error { public:   BadFileName(const string& filename) throw(); }; BadFileName::BadFileName(const string& filename) throw() : runtime_error("bad file name: " + filename) { } class AccessViolation : public runtime_error { public:   AccessViolation(const string& filename) throw(); }; AccessViolation::AccessViolation(const string& filename) throw() : runtime_error("access violation on file " + filename) { } 

The next step is to define a File class that pretends to check the file name and access privileges. The code for this actually uses hard-coded names: the name BadName.txt represents a bad file name, and the name NoAccess.txt represents a file that cannot be accessed. In reality this member function would call some system routines to determine whether the file name was good or bad and whether the file was accessible or not.

 class File { public:   File(const string& filename) throw(BadFileName, AccessViolation); }; File::File(const string& filename) throw(BadFileName, AccessViolation) {   cout << "File::File(): Opening " << filename << "\n";   if (filename == "NoAccess.txt")     throw AccessViolation();   if (filename == "BadName.txt")     throw BadFileName();   cout << "  Successfully opened\n"; } 

The next step is to declare some functions that catch and partially recover from these exceptions.

 void first(const string& filename) throw(); void second(const string& filename) throw(BadFileName); int main() {   first("GoodFile.txt");   first("BadName.txt");   first("NoAccess.txt"); } void first(const string& filename) throw() {   try {     second(filename);   }   catch (BadFileName& e) {     cout << "  first(): " << e.what() << ": Finish recovery\n";   } } void second(const string& filename) throw(BadFileName) {   try {     File x(filename);   }   catch (BadFileName& e) {     cout << "  second(): " << e.what() << ": Partial recovery\n";     throw;                                           <-- 1   }   catch (AccessViolation& e) {     cout << "  second(): " << e.what() << ": Full recovery\n";   } } 

(1) Rethrow the BadFileName exception

The output of the program is as follows.

 File::File(): Opening GoodFile.txt   Successfully opened File::File(): Opening BadName.txt   second(): bad file name: BadName.txt: Partial recovery   first(): bad file name: BadName.txt: Finish recovery File::File(): Opening NoAccess.txt   first(): access violation on file NoAccess.txt: Full recovery 


C++ FAQs
C Programming FAQs: Frequently Asked Questions
ISBN: 0201845199
EAN: 2147483647
Year: 2005
Pages: 566
Authors: Steve Summit

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net