473,414 Members | 1,746 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,414 software developers and data experts.

When exceptions aren't enough: Dealing with runtime errors.

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

Jul 24 '05 #1
4 1727
Ian
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
Jul 25 '05 #2
wij
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.

Jul 25 '05 #3
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

Jul 25 '05 #4
Ian
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

Jul 25 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

26
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...
24
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...
13
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...
12
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...
6
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...
4
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...
8
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...
4
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...
9
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...
0
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
0
BarryA
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...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
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...
0
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...
0
jinu1996
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...
0
tracyyun
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...
0
isladogs
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...
0
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...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.