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 4 1727
Aaron W. LaFramboise wrote: 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.
Log the error in an appropriate place, either you application's log file
if it has one, or via you system's log interface. 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.
In this case, either assert or throw an exception that is caught in
main, printing a message and aborting.
I prefer the former, at least on a platform where you can leave a core
file for later analysis.
Ian
Aaron W. LaFramboise wrote: .. 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.
I have a developing library, which tries to solve problems
like you mentioned. http://sourceforge.net/projects/libwx/
Hope it could help. Suggestion and relevant questions are
welcome. IMHO(from articles there), "close" stuff has to
succeed, no matter what it returned.
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.
It is thought as class design problem, see also the suggested
link.
On Mon, 25 Jul 2005 12:01:54 +1200, Ian <no***@nowhere.com> wrote: Aaron W. LaFramboise wrote: Case 1: An error was encountered, but this does not prevent continued execution. Log the error in an appropriate place, either you application's log file if it has one, or via you system's log interface.
If I am writing a reusable file-handling component, for example, it is
the likely case that the component has no idea what the correct place
is. For example, if you were re-implementing something similar to
std::filebuf, how would you know how to report errors from ~filebuf?
Notice that the standard cleverly (or not) avoids this problem by
ignoring the cause of errors in general (There is no standard way to
find out why filebuf::open() failed, for example.), and ignoring
failures in close() in the destructor in particular. Case 2: An error was encountered, and it probably will prevent continued execution. In this case, either assert or throw an exception that is caught in main, printing a message and aborting.
You can't throw from a destructor. assert() is not acceptable because
this is a runtime error, not a logic error. The application should be
able to exit gracefully. A core file is not helpful here, because
there is no bug.
Aaron W. LaFramboise
Aaron W. LaFramboise wrote: On Mon, 25 Jul 2005 12:01:54 +1200, Ian <no***@nowhere.com> wrote:
Aaron W. LaFramboise wrote:
Case 1: An error was encountered, but this does not prevent continued execution.
Log the error in an appropriate place, either you application's log file if it has one, or via you system's log interface.
If I am writing a reusable file-handling component, for example, it is the likely case that the component has no idea what the correct place is. For example, if you were re-implementing something similar to std::filebuf, how would you know how to report errors from ~filebuf?
You could, for your own errors, use a static error member?
Notice that the standard cleverly (or not) avoids this problem by ignoring the cause of errors in general (There is no standard way to find out why filebuf::open() failed, for example.), and ignoring failures in close() in the destructor in particular. Case 2: An error was encountered, and it probably will prevent continued execution.
In this case, either assert or throw an exception that is caught in main, printing a message and aborting.
You can't throw from a destructor. assert() is not acceptable because this is a runtime error, not a logic error. The application should be able to exit gracefully. A core file is not helpful here, because there is no bug.
Well you could if there wasn't anything else to do. With assert, the
error condition could be something outside of the code's control, maybe
a problem with the underlying operating system. So one of the code's
assumptions is false, which is fair grounds for an assert.
Ian Aaron W. LaFramboise This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Zunbeltz Izaola |
last post by:
Hi,
I've the following problem with try/exception.
I've a try block that will raise some exceptions.
I want the program to ignore this exceptions completely.
Is it possible?
Thanks in...
|
by: mag31 |
last post by:
Is there any way to find out if a particular .net function will throw an
exception without first generating the exception?
I am using structured exception handling i.e. try catch finally blocks...
|
by: kelvSYC |
last post by:
What I want to do is to read a 32-bit unsigned integer (let's call that
u32) in little-endian form from an fstream. Would it be better if my
function went like this:
// returns false if an...
|
by: Vasco Lohrenscheit |
last post by:
Hi,
I have a Problem with unmanaged exception. In the debug build it works
fine to catch unmanaged c++ exceptions from other dlls with
//managed code:
try
{
//the form loads unmanaged dlls...
|
by: Leslie |
last post by:
I am attempting to handle errors by using Application_Error. This seems to
work fine in most situations. However, if the exception occurs during the
Application_Start method, the stand error...
|
by: Steve |
last post by:
I have read a couple articles online, read my Jesse Liberty book but I am
still confused as to just what the best practices are for using exceptions.
I keep changing how I'm working with them and...
|
by: Olivier BESSON |
last post by:
Hello,
VB.NET 1.1
IIS 6
I'm developping a winform client app of a web service of mine.
I used to set the IDE with "halt in debugger" on "common language runtime
exceptions".
Every time i...
|
by: rwf_20 |
last post by:
I'm seeing incorrect (I think) behavior in the event of an exception
thrown in a native C++ library. Basically, the stack appears to
unwind correctly if the caller is native, but incorrectly if...
|
by: =?Utf-8?B?UmFq?= |
last post by:
How do I know which methods will throw exception when I am using FCL or other
third party .Net library?
I am developer of mostly native Windows applications and now .Net. After
working few...
|
by: emmanuelkatto |
last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud.
Please let me know.
Thanks!
Emmanuel
|
by: BarryA |
last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
by: Hystou |
last post by:
There are some requirements for setting up RAID:
1. The motherboard and BIOS support RAID configuration.
2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
|
by: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome a new...
|
by: conductexam |
last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
| |