Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Do you have experience with exceptions?

Reply
Thread Tools

Do you have experience with exceptions?

 
 
DeMarcus
Guest
Posts: n/a
 
      05-05-2010
Hi,

If you want to design your own exceptions there are several guidelines
out there. One of them is this from boost.

http://www.boost.org/community/error_handling.html

If you look at their recommendations I would like to skip all items and
just focus on item 6. In short it says; in the exception, don't provide
messages, provide objects involved with the problem.

I claim that this is (almost) completely wrong, and my arguments for
this are the following.

*) A function may throw several different exceptions of the same type,
making it impossible for the receiver to understand what the attached
objects mean. E.g. OutOfBoundsException with an attached integer 42 may
mean that the loadModuleWithID() tried to load an ID that doesn't exist,
or it may mean that a subroutine to loadModuleWithID() tried to read out
of bounds in an XML file.


*) If a short message is created and attached to the exception, an
exception message stack unwinding may be more descriptive than what the
handler can put together on its own. E.g. it would probably be more
descriptive to see the following.

OutOfBoundsException - Tried to read XML section 42. Only 40 exist.
FileReadException - Could not read XML file config.xml.
NoSuchEntryException - Could not load module with ID 4711.

instead of

NoSuchEntryException - Out of bounds: 42. File: config.xml. ID: 4711.


*) Lower coupling promotes program correctness. If the receiver of an
exception has to understand the meaning of the attached objects, that in
turn means that we couple the function and caller. If the creation of
the exception changes slightly in the function, all callers have to be
updated!


I claim that a stack of independent exception messages is more
descriptive than trying to forward objects that an exception handler
shall interpret.

Do you have concrete examples from your experience with exceptions? I
would like to hear your opinion, especially if you don't agree with me.


Thanks,
Daniel

 
Reply With Quote
 
 
 
 
Alf P. Steinbach
Guest
Posts: n/a
 
      05-05-2010
* DeMarcus:
>
> If you want to design your own exceptions there are several guidelines
> out there. One of them is this from boost.
>
> http://www.boost.org/community/error_handling.html
>
> If you look at their recommendations I would like to skip all items and
> just focus on item 6. In short it says; in the exception, don't provide
> messages, provide objects involved with the problem.
>
> I claim that this is (almost) completely wrong, and my arguments for
> this are the following.
>
> *) A function may throw several different exceptions of the same type,
> making it impossible for the receiver to understand what the attached
> objects mean. E.g. OutOfBoundsException with an attached integer 42 may
> mean that the loadModuleWithID() tried to load an ID that doesn't exist,
> or it may mean that a subroutine to loadModuleWithID() tried to read out
> of bounds in an XML file.
>
>
> *) If a short message is created and attached to the exception, an
> exception message stack unwinding may be more descriptive than what the
> handler can put together on its own. E.g. it would probably be more
> descriptive to see the following.
>
> OutOfBoundsException - Tried to read XML section 42. Only 40 exist.
> FileReadException - Could not read XML file config.xml.
> NoSuchEntryException - Could not load module with ID 4711.
>
> instead of
>
> NoSuchEntryException - Out of bounds: 42. File: config.xml. ID: 4711.
>
>
> *) Lower coupling promotes program correctness. If the receiver of an
> exception has to understand the meaning of the attached objects, that in
> turn means that we couple the function and caller. If the creation of
> the exception changes slightly in the function, all callers have to be
> updated!


Yeah, agreed. Good points. Especially last one.


> I claim that a stack of independent exception messages is more
> descriptive than trying to forward objects that an exception handler
> shall interpret.
>
> Do you have concrete examples from your experience with exceptions? I
> would like to hear your opinion, especially if you don't agree with me.


Constructing an exception object shouldn't throw, or should have very low chance
of throwing. This means that designing your own /safe/ exception class is hard:
you first have to design and implement a reasonable array smart pointer, then a
reasonable non-mutable string class, then exceptions -- and there's a catch 22
for how to deal with exceptions for the string class...

Exceptions need not support chaining but they do need to support cloning and
rethrowing via some virtual method, in order to propagate exceptions safely
through C code.

The focus on providing a lot of information via exception objects is as I see it
wrong-headed for C++ (although it can be meaningful in a scripting context). In
C++ bugs should IMO preferentially trigger asserts, not raise exceptions, and
for a failure-indicating exception the type should be enough (and often is much
more than enough) for the handling code. A decent C++ debugger lets you break on
first throw, and that's where you're headed anyway when it's a bug. All that
information-gathering and forwarding for a "rich" exception is mostly additional
things that can go wrong, and it adds complexity & inefficiency.


Cheers, & hth.,

- Alf
 
Reply With Quote
 
 
 
 
DeMarcus
Guest
Posts: n/a
 
      05-05-2010
On 2010-05-05 20:27, Alf P. Steinbach wrote:
> * DeMarcus:
>>
>> If you want to design your own exceptions there are several guidelines
>> out there. One of them is this from boost.
>>
>> http://www.boost.org/community/error_handling.html
>>
>> If you look at their recommendations I would like to skip all items and
>> just focus on item 6. In short it says; in the exception, don't provide
>> messages, provide objects involved with the problem.
>>
>> I claim that this is (almost) completely wrong, and my arguments for
>> this are the following.
>>
>> *) A function may throw several different exceptions of the same type,
>> making it impossible for the receiver to understand what the attached
>> objects mean. E.g. OutOfBoundsException with an attached integer 42 may
>> mean that the loadModuleWithID() tried to load an ID that doesn't exist,
>> or it may mean that a subroutine to loadModuleWithID() tried to read out
>> of bounds in an XML file.
>>
>>
>> *) If a short message is created and attached to the exception, an
>> exception message stack unwinding may be more descriptive than what the
>> handler can put together on its own. E.g. it would probably be more
>> descriptive to see the following.
>>
>> OutOfBoundsException - Tried to read XML section 42. Only 40 exist.
>> FileReadException - Could not read XML file config.xml.
>> NoSuchEntryException - Could not load module with ID 4711.
>>
>> instead of
>>
>> NoSuchEntryException - Out of bounds: 42. File: config.xml. ID: 4711.
>>
>>
>> *) Lower coupling promotes program correctness. If the receiver of an
>> exception has to understand the meaning of the attached objects, that in
>> turn means that we couple the function and caller. If the creation of
>> the exception changes slightly in the function, all callers have to be
>> updated!

>
> Yeah, agreed. Good points. Especially last one.
>
>
>> I claim that a stack of independent exception messages is more
>> descriptive than trying to forward objects that an exception handler
>> shall interpret.
>>
>> Do you have concrete examples from your experience with exceptions? I
>> would like to hear your opinion, especially if you don't agree with me.

>
> Constructing an exception object shouldn't throw, or should have very
> low chance of throwing. This means that designing your own /safe/
> exception class is hard: you first have to design and implement a
> reasonable array smart pointer, then a reasonable non-mutable string
> class, then exceptions -- and there's a catch 22 for how to deal with
> exceptions for the string class...
>
> Exceptions need not support chaining but they do need to support cloning
> and rethrowing via some virtual method, in order to propagate exceptions
> safely through C code.
>
> The focus on providing a lot of information via exception objects is as
> I see it wrong-headed for C++ (although it can be meaningful in a
> scripting context). In C++ bugs should IMO preferentially trigger
> asserts, not raise exceptions, and for a failure-indicating exception
> the type should be enough (and often is much more than enough) for the
> handling code. A decent C++ debugger lets you break on first throw, and
> that's where you're headed anyway when it's a bug. All that
> information-gathering and forwarding for a "rich" exception is mostly
> additional things that can go wrong, and it adds complexity & inefficiency.
>
>


I agree with you that too much complexity is put in the exceptions. The
problem is the reality. If you ship a product and the customer on the
other side of the globe calls you in the middle of the night screaming;
"It crashed!". Then it's nice to start with the log file instead of
jumping out of the bed, book a flight ticket to go there have a look at
the core dump.

If the log file says; "OutOfBoundsException - Tried to read XML section
42. Only 40 exist.", there may be reason to start up the computer. If
the log file instead says; "FileReadException - Could not read XML file
config.xml. File access denied.", then you could tell the administrator
to grant the application access to the directory, and then you can go
back to sleep.

My point is that a core dump and a debugger are invaluable tools, but
when dealing with customers you want to filter out as many simple bugs
as possible before starting up your debugger.




 
Reply With Quote
 
Richard
Guest
Posts: n/a
 
      05-05-2010
[Please do not mail me a copy of your followup]

In addition to the comments of the original poster and Alf, I'll just
add that I don't end up using exceptions for finding programming
errors. Since I've switched to test-driven development, I find that
my programming errors are all found much, much earlier by tests. I
use exceptions for things like "whoops, the network died while we were
in the middle of talking", not things like array indices out of
bounds.

Having said that, I do use mechanisms that translate error codes into
exceptions when I'm not expecting the underlying code to ever fail.
Occasionally these result in exceptions due to programming errors. In
areas where I code in C++, COM objects and C style APIs are
commonplace.

I map failed COM HRESULTs to exceptions except in the rare occasions
where you are doing something like querying the size of a buffer and the
function normally returns E_MORE_DATA or whatever to indicate that its
telling you the size required. Similarly, when I call something like
::GetDC, I expect it to return me a real HDC. When it doesn't, I throw.
This is a programming error, there aren't any real world situations
where GetDC will return zero unless I made a mistake elsewhere.

This practice has saved me valuable time in the debugger and I mostly
adopted that "map C/COM style error codes to exceptions" habit several
years before I adopted the test-driven development habit. Test-driven
development has saved me even *more* time in the debugger, but the
exception technique helped a lot.
--
"The Direct3D Graphics Pipeline" -- DirectX 9 draft available for download
<http://legalizeadulthood.wordpress.com/the-direct3d-graphics-pipeline/>

Legalize Adulthood! <http://legalizeadulthood.wordpress.com>
 
Reply With Quote
 
Öö Tiib
Guest
Posts: n/a
 
      05-05-2010
On 5 mai, 21:27, "Alf P. Steinbach" <al...@start.no> wrote:
>
> The focus on providing a lot of information via exception objects is as I see it
> wrong-headed for C++ (although it can be meaningful in a scripting context). In
> C++ bugs should IMO preferentially trigger asserts, not raise exceptions, and
> for a failure-indicating exception the type should be enough (and often is much
> more than enough) for the handling code. A decent C++ debugger lets you break on
> first throw, and that's where you're headed anyway when it's a bug. All that
> information-gathering and forwarding for a "rich" exception is mostly additional
> things that can go wrong, and it adds complexity & inefficiency.


Some product feels like scripting context despite it is fully C++.
Consider:
Group of tough guys are maintaining a framework. Hundreds are sending
plugins for integration from all over the globe. Thousands are using
integrated product. Work is constant, patch, upgrade or new release
per month.

Asserting in such framework is rather pointless. Framework should be
truly unbreakable. It should very clearly blame those plugins from all
channels (trace, log, user interface) but still keep being alive. On
worst case it should kick out bad (lets say hanging) plugin and
restart itself. Otherwise if the product is doing anything mission
critical the above mentioned tough guys can never sleep.
 
Reply With Quote
 
Ian Collins
Guest
Posts: n/a
 
      05-05-2010
On 05/ 6/10 10:07 AM, Paavo Helde wrote:
> DeMarcus<> wrote:
>
>> Hi,
>>
>> If you want to design your own exceptions there are several guidelines
>> out there. One of them is this from boost.
>>
>> http://www.boost.org/community/error_handling.html
>>
>> If you look at their recommendations I would like to skip all items and
>> just focus on item 6. In short it says; in the exception, don't provide
>> messages, provide objects involved with the problem.

>
> In my reading, it says almost the opposite: *in addition* to the message,
> provide the relevant data separately for the potential exception handlers
> needing that data. This does not mean that one could not include this data
> also in the error message returned by what().


I agree. It's pretty clear from (emphasis mine): "If you *only* expose
a textual representation of those numbers in the what() string" that the
guideline is not recommending against messages.

> Of course handling of this extra data is more difficult, but this does
> concern only exception handlers interested in that data. Other handlers can
> just dump the what() string somewhere and be done with it.


I agree again. My default system call exception base class exposes the
name, line, file and errno value of failed system calls as well as
providing a formatted message via what(). So I can either catch and
attempt to recover, or simply call what() and exit.

Another important point made there is to defer the formatting to the
what() member. In order to do that, the relevant data has to be
included in the exception object.

--
Ian Collins
 
Reply With Quote
 
DeMarcus
Guest
Posts: n/a
 
      05-06-2010
On 2010-05-05 22:32, Richard wrote:
> [Please do not mail me a copy of your followup]
>
> In addition to the comments of the original poster and Alf, I'll just
> add that I don't end up using exceptions for finding programming
> errors. Since I've switched to test-driven development, I find that
> my programming errors are all found much, much earlier by tests. I
> use exceptions for things like "whoops, the network died while we were
> in the middle of talking", not things like array indices out of
> bounds.
>


I agree, out of bounds is maybe not the best example, but still, there
could be a bad configuration file composed by the user that goes out of
bounds somewhere. In the end the correct message would be something
like; "Your config file is ill-formed", but it would be nice to see the
stack trace of that.

> Having said that, I do use mechanisms that translate error codes into
> exceptions when I'm not expecting the underlying code to ever fail.
> Occasionally these result in exceptions due to programming errors. In
> areas where I code in C++, COM objects and C style APIs are
> commonplace.
>
> I map failed COM HRESULTs to exceptions except in the rare occasions
> where you are doing something like querying the size of a buffer and the
> function normally returns E_MORE_DATA or whatever to indicate that its
> telling you the size required. Similarly, when I call something like
> ::GetDC, I expect it to return me a real HDC. When it doesn't, I throw.
> This is a programming error, there aren't any real world situations
> where GetDC will return zero unless I made a mistake elsewhere.
>
> This practice has saved me valuable time in the debugger and I mostly
> adopted that "map C/COM style error codes to exceptions" habit several
> years before I adopted the test-driven development habit. Test-driven
> development has saved me even *more* time in the debugger, but the
> exception technique helped a lot.


Do you have any favorite sites about test-driven development? I want to
dig even deeper down into that.


 
Reply With Quote
 
Ian Collins
Guest
Posts: n/a
 
      05-06-2010
On 05/ 7/10 09:36 AM, DeMarcus wrote:
>
> Do you have any favorite sites about test-driven development? I want to
> dig even deeper down into that.
>

Have a look at

http://www.agiledata.org/essays/tdd.html

for an introduction.

I recommend (and use) googletest and CPPUinit for my tests.

--
Ian Collins
 
Reply With Quote
 
DeMarcus
Guest
Posts: n/a
 
      05-06-2010
On 2010-05-06 00:07, Paavo Helde wrote:
> DeMarcus<> wrote in news:4be1b4e8$0$278
> $:
>
>> Hi,
>>
>> If you want to design your own exceptions there are several guidelines
>> out there. One of them is this from boost.
>>
>> http://www.boost.org/community/error_handling.html
>>
>> If you look at their recommendations I would like to skip all items and
>> just focus on item 6. In short it says; in the exception, don't provide
>> messages, provide objects involved with the problem.

>
> In my reading, it says almost the opposite: *in addition* to the message,
> provide the relevant data separately for the potential exception handlers
> needing that data. This does not mean that one could not include this data
> also in the error message returned by what().
>


Ok, you're right there.

> Of course handling of this extra data is more difficult, but this does
> concern only exception handlers interested in that data. Other handlers can
> just dump the what() string somewhere and be done with it.
>


Now, I do respect the whole boost community, including the boost
exceptions, however, I still don't know whether providing arbitrary data
with a general exception (or any object for that matter) is good design.

As a receiver you should know for sure what data you're getting.
Therefore I would rather see a subclass to the boost exception providing
that extra data in the interface.

> To me it seems you are trying to break through an open door.
>


Don't get me wrong. This discussion is not about whether boost exception
is good or not, I just took boost as an example. The discussion is about
whether it is good design to provide arbitrary data with an object; in
this case an exception.



 
Reply With Quote
 
Ian Collins
Guest
Posts: n/a
 
      05-06-2010
On 05/ 7/10 09:56 AM, DeMarcus wrote:
> On 2010-05-06 00:07, Paavo Helde wrote:
>
>> Of course handling of this extra data is more difficult, but this does
>> concern only exception handlers interested in that data. Other
>> handlers can
>> just dump the what() string somewhere and be done with it.
>>

>
> Now, I do respect the whole boost community, including the boost
> exceptions, however, I still don't know whether providing arbitrary data
> with a general exception (or any object for that matter) is good design.


I don't see anyone advocating providing arbitrary data with a general
exception.

> As a receiver you should know for sure what data you're getting.
> Therefore I would rather see a subclass to the boost exception providing
> that extra data in the interface.
>
>> To me it seems you are trying to break through an open door.

>
> Don't get me wrong. This discussion is not about whether boost exception
> is good or not, I just took boost as an example. The discussion is about
> whether it is good design to provide arbitrary data with an object; in
> this case an exception.


See my other response.

I don't provide arbitrary data, I include enough for the catcher to
either bail, print something meaningful or attempt recovery.

One of the design considerations raised is whether to process the
available information in the exception constructor and store this result
in the "what" string, or store the information in the exception and
perform the processing in the what() member. I prefer the latter.
There's enough information in the exception object to make a choice when
it is caught.

--
Ian Collins
 
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
I have no programming experience. Would you recommend C? Enteng C Programming 111 02-02-2007 05:20 AM
a question: Do I have to have some work experience before taking the exam jessi MCAD 3 04-04-2005 10:04 AM
What do you want to know when you ask, "Anyone have experience with ... ?" Frank ess Digital Photography 10 12-12-2004 12:47 AM
Xandros - an experience you have to have to believe. Dave - Dave.net.nz NZ Computing 9 11-17-2004 02:50 AM
Is there a person who I experience absurd event that experience? PS2 gamer Cisco 4 06-01-2004 07:52 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57