|
Boost : |
From: Don G (dongryphon_at_[hidden])
Date: 2005-04-04 00:44:40
A technique I have used and evolved over the past few years is a more
powerful way to handle errors, derived from std::exception. Following
are the motivations and some details. I am curious to hear if others
find this a useful facility.
The current std::exception class suffers from several problems that
limit its use:
1. It cannot be polymorphically copied for storage.
2. It has no virtual "rethrow" method.
3. Instances cannot be extended with extra details.
4. Underlying system error codes are lost.
Either of the first two problems would prevent effective marshalling
of an instance, as would be needed in an asynchronous environment.
The 3rd problem greatly reduces the ability to capture pertinent
information during the unwinding process.
Example 1 - Capturing an error for later use
class StateMachine
{
private:
errorinfo::ptr error_;
void called_on_error (const errorinfo & err)
{
error_ = err.clone();
}
};
There are two mechanisms for adding error information: Extending and
Chaining. The simpler case is extending an errorinfo object. The
reason to extend an errorinfo is that the caller will have more
details about the context of the failure than the thrower. Typically
a lower level method may encounter a problem and throw an exception,
but doesn't know _why_ it was called. The caller, however, knows more
about the "why" and can add those details before letting the
exception unwind further.
Example 2 - Extending the description of an error
try
{
do_something();
do_something_else();
do_something_more();
}
catch (const error::logic & x)
{
x.extend("Failed to achieve my goal").raise();
}
The idea behind chaining is similar to that of extending. When
extending an errorinfo, only the description (reported by the what()
method) is changed. The type of errorinfo is unchanged. There are
times that what the caller may be doing would change the kind of
failure reported upwards. For example, a method that searches for
something might throw error_not_found. The caller might decide that
this would be an inappropriate type to throw to his caller and so
would want to catch error_not_found and throw some other exception.
To preserve the original error_not_found, we can chain it with the
newly created exception.
Example 3 - Chaining errors
try
{
find_something();
}
catch (const error::not_found & x)
{
throw error_whatever(x.clone(), "Failed in some way");
}
I have posted errorinfo.zip on the Yahoo files section for those
wanting more detail.
__________________________________
Do you Yahoo!?
Take Yahoo! Mail with you! Get it on your mobile phone.
http://mobile.yahoo.com/maildemo
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk