Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > When exceptions aren't enough: Dealing with runtime errors.

Reply
Thread Tools

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

 
 
Aaron W. LaFramboise
Guest
Posts: n/a
 
      07-24-2005
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

 
Reply With Quote
 
 
 
 
Ian
Guest
Posts: n/a
 
      07-25-2005
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
 
Reply With Quote
 
 
 
 
wij@seed.net.tw
Guest
Posts: n/a
 
      07-25-2005
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.

 
Reply With Quote
 
Aaron W. LaFramboise
Guest
Posts: n/a
 
      07-25-2005
On Mon, 25 Jul 2005 12:01:54 +1200, Ian <(E-Mail Removed)> 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:pen() 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

 
Reply With Quote
 
Ian
Guest
Posts: n/a
 
      07-25-2005
Aaron W. LaFramboise wrote:
> On Mon, 25 Jul 2005 12:01:54 +1200, Ian <(E-Mail Removed)> 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:pen() 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
>

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Dealing with exceptions bvdp Python 19 03-03-2013 11:01 PM
Dealing with multiple inputfiles at runtime? none C++ 2 05-04-2010 08:18 PM
Dealing with exceptions when using ScheduledThreadPoolExecutor AndyColeman Java 1 11-28-2006 01:39 PM
Checked exceptions vs unchecked exceptions Ahmed Moustafa Java 5 07-14-2004 01:46 PM
Custom exceptions -- inherit from exceptions.Exception? Paul Miller Python 3 11-12-2003 09:24 AM



Advertisments