Archived

This topic is now archived and is closed to further replies.

Mr Cucumber

Error handling options

Recommended Posts

Mr Cucumber    122
I guess the best way to deal with error handling in a C++ program is to use exceptions instead of return values. But what is the best way to use exceptions? The options I think of is to either put a try/catch in every function, or to put all code into one try statement and catch the errors efter that. If I go with version one I get the benefit that each function is on their own. If an error occur that doesnt need to shutdown the program the program can continue after the function. Maybe this takes away the whole point of exceptions. What do you think, and how do you deal with errors yourself?

Share this post


Link to post
Share on other sites
Fruny    1658
I know it may not sound very helpful, but the best place to handle exceptions is "as soon as you can really do something about the problem".

If the first function fails, does it make sense to move on to the next anyway ? Is some kind of recovery possible, or should the whole sequence be aborted ? Should you try calling it again a few times before aborting ?

For example, if you can''t initialize the graphics library, there is no point in selecting a graphics mode, but if one graphics mode doesn''t work out, you might try another one instead.

If the whole sequence is to be aborted, put the try/catch block around it. If some function''s failure can be recovered from, put a try/catch block around that one too.

You may also want to catch an exception at some level, do some cleanup and rethrow it again, or throw another one of your own if the client code doesn''t really care about *which* error occured, only that an error occured - you could catch GraphicsInitFailed and CouldNotInitializeSoundSystem, then throw your own InitializationFailed. Or something...

Better, when possible (and appropriate), arrange your exceptions in a class hierarchy, so that you can catch the base exception whenever any of the derived exception is thrown. If GraphicsInitFailed and SoundInitFailed both derive from InitFailed, catching that last one will also catch the other two.

Deriving your own exceptions from the standard C++ exceptions (e.g. std::runtime_error) may be a good idea.

Finally, you can use destructors to do cleanup. When an exception is thrown, all (fully constructed) local objects are destroyed. Which means that any resource they acquired when you created them (e.g. files, thread locks, memory ...) is released and your exception handlers (cleanup code) are much, much simplified.

This is the Resource Acquisition Is Initialization (RAII) idiom. Learn to use it. Learn to love it.

As a bonus, here''s a bit of code that tries a function several times then gives up... with a justified use of goto


class FooFailed {};
class BarFailed {};

int Foo()
{
throw FooFailed(); // Always throws

return 0;
}

int Bar()
{
int tries = 3;

retry:
try
{
return Foo();
}
catch( FooError& )
{
if(--tries>0)
goto retry;
else
throw BarFailed();
}
}


Exceptions force you to catch all errors, so it''s sure going to involve extra typing. But at least, exception hierarchies let you process (or discard) whole groups of similar exceptions.


[ Start Here ! | How To Ask Smart Questions | Recommended C++ Books | C++ FAQ Lite | Function Ptrs | CppTips Archive ]
[ Header Files | File Format Docs | LNK2001 | C++ STL Doc | STLPort | Free C++ IDE | Boost C++ Lib | MSVC6 Lib Fixes ]

Share this post


Link to post
Share on other sites
petewood    819
writing exception safe code will predominantly not involve try/catch

there are numerous articles on gotw.ca which were compiled into the books 'exceptional c++' and 'more exceptional c++' by Herb Sutter.

Check out the website. Read through the gotw and other articles to do with exception safety. There's lots of other good stuff there too.

I'll come back with some links to specific articles on the site if you want but you're best having a root around yourself.

edit:
this gotw deals with misconceptions about using try/catch.
gotw 65
Try and Catch Me
Difficulty: 3 / 10

Is exception safety all about writing try and catch in the right places? If not, then what? And what kinds of things should you consider when developing an exception safety policy for your software?


This one includes a recap of Exception Safety Canonical Forms.
gotw 59
Exception-Safe Class Design, Part 1: Copy Assignment
Difficulty: 7 / 10

Is it possible to make any C++ class strongly exception-safe, for example for its copy assignment operator? If so, how? What are the issues and consequences?


[edited by - petewood on July 8, 2003 11:19:09 AM]

Share this post


Link to post
Share on other sites
petewood    819
quote:
As a bonus, here''s a bit of code that tries a function several times then gives up... with a justified use of goto

not justified


class FooFailed {};
class BarFailed {};

int Foo()
{
throw FooFailed(); // Always throws

return 0;
}

int Bar()
{
int tries = 3;

while(tries>0) {
try
{
return Foo();
}
catch( FooError& )
{
--tries;
}
}
throw BarFailed();
}


Share this post


Link to post
Share on other sites
Fruny    1658
petewood - your code doesn't do the same thing. Mine only retries if an exception is thrown (the fact that Foo always throws is just for the example). And only throws after having retried 3 times. If no retry is needed, it doesn't throw and would move on to whatever code follows.


[ Start Here ! | How To Ask Smart Questions | Recommended C++ Books | C++ FAQ Lite | Function Ptrs | CppTips Archive ]
[ Header Files | File Format Docs | LNK2001 | C++ STL Doc | STLPort | Free C++ IDE | Boost C++ Lib | MSVC6 Lib Fixes ]


[edited by - Fruny on July 8, 2003 5:25:12 PM]

Share this post


Link to post
Share on other sites
wirewolf    122
Foo() is going to return if it is successful tho... or at least completes, so his code is the same. The thing I do like about your example, Fruny, is that it is easier for me, personally, to figure out what is happening in the function. If it was a rather long function I might like to see the goto instead of searching for the while. That is really just a personal thing tho.

Colby

Share this post


Link to post
Share on other sites
haro    502
Error handling should not be used a standard method of handling typical errors. There is very significant overhead whenever an exception is actually thrown and so using exceptions in a method that is likely to actually throw exceptions a reasonably large amount of times is a bad idea, if this function is called multiple times.

Share this post


Link to post
Share on other sites