A
Aaron W. LaFramboise
I'm seeking a solution to my C++-life long dilemma of how to deal with
errors when exceptions aren't appropriate. Below I highlight two
error cases, which mainly occur when trying to handle "unexpected"
errors on system interfaces. I am an experienced modern C++
programmer, and I'm mainly interested in the case where the error is
in a generic, reusable component where invasive control over the user
is unacceptable.
Case 1: An error was encountered, but this does not prevent continued
execution.
In these cases, it is generally inappropriate to throw an exception,
and in some situations, due to the nature of the operation, it might
be 'too late' (the operation has already been completed) or impossible
(in a destructor) to throw an exception.
For example, an error is encountered while trying to close a file.
This most commonly happens for files with physical storage on remote
filesystems. Depending on the situation, this may not be a serious
condition by itself.
Another example might be closing a temporary pipe at the completion of
some sort of IPC operation. It may be the case that this failure is
entirely irrelevent, and that execution can (and should) continue.
Yet, the error should be reported, as it may have some relevence.
Case 2: An error was encountered, and it probably will prevent
continued execution.
In these cases, we would like to throw an exception, but we can't,
probably because we're in a destructor.
An example of this would be a class that needs to allocate memory for
some reason in its destructor, and this allocation fails.
Solutions
Well, I haven't found a good one.
Traditional C solutions tend to involve doing something like writing
to stderr, which is not appropriate in the general case for modern
code.
For many of the cases, we want stack-based processing similar to C++
exceptions: we just don't want the part where it kills the current
flow of execution. Resumptions would be perfect for many situations,
yet there seems to be little interest in implementing these for C++.
I'd speculate that this is a fairly common problem, and that it is
fairly common to do the wrong thing, probably on the dubious
nihilistic grounds that "we're screwed anyway" or "i don't care." How
many times does code like this get written:
my_file::~my_file() {
close(file_handle); // not checking return value.. oh well
}
Has anyone found a good solution to these catagories of problems?
Aaron W. LaFramboise
errors when exceptions aren't appropriate. Below I highlight two
error cases, which mainly occur when trying to handle "unexpected"
errors on system interfaces. I am an experienced modern C++
programmer, and I'm mainly interested in the case where the error is
in a generic, reusable component where invasive control over the user
is unacceptable.
Case 1: An error was encountered, but this does not prevent continued
execution.
In these cases, it is generally inappropriate to throw an exception,
and in some situations, due to the nature of the operation, it might
be 'too late' (the operation has already been completed) or impossible
(in a destructor) to throw an exception.
For example, an error is encountered while trying to close a file.
This most commonly happens for files with physical storage on remote
filesystems. Depending on the situation, this may not be a serious
condition by itself.
Another example might be closing a temporary pipe at the completion of
some sort of IPC operation. It may be the case that this failure is
entirely irrelevent, and that execution can (and should) continue.
Yet, the error should be reported, as it may have some relevence.
Case 2: An error was encountered, and it probably will prevent
continued execution.
In these cases, we would like to throw an exception, but we can't,
probably because we're in a destructor.
An example of this would be a class that needs to allocate memory for
some reason in its destructor, and this allocation fails.
Solutions
Well, I haven't found a good one.
Traditional C solutions tend to involve doing something like writing
to stderr, which is not appropriate in the general case for modern
code.
For many of the cases, we want stack-based processing similar to C++
exceptions: we just don't want the part where it kills the current
flow of execution. Resumptions would be perfect for many situations,
yet there seems to be little interest in implementing these for C++.
I'd speculate that this is a fairly common problem, and that it is
fairly common to do the wrong thing, probably on the dubious
nihilistic grounds that "we're screwed anyway" or "i don't care." How
many times does code like this get written:
my_file::~my_file() {
close(file_handle); // not checking return value.. oh well
}
Has anyone found a good solution to these catagories of problems?
Aaron W. LaFramboise