When use what Error-Handling

Started by
23 comments, last by ApochPiQ 12 years, 9 months ago
Hi!

I'm still programming my little game and just wondered how to best deal with unexpected behaviour, i.e. when something fails that should work.
Well the short term to describe this is Exception Handling, but when should I use what method?

For example, if I expect my Func1 to return "true" and I check this via an if I could either throw new std::exception(...); and have to catch it somewhere or I could return NULL for the function calling that function and just pass the problem on, what the exception also does somehow.

So I would like to have some opinions about this.

Thanks,
Xaser
Advertisement
Humm, it's not nice to pass on the problem, -how would you then (easily) find the cause of the problem? Too much exception handling, or in performance-critical parts of the code is not good, but if you're not releasing anything yet it might be good for increased bug tracability. I'd definitely not return null... If it can be avoided, and mostly it can.
Well its a general problem, for debugging as well as for the release. The release version will have to be able to handle such problems as well.

Both ways do their job and I for myself can't really tell what has more advantages in what situation, thats why I'm asking.

Xaser

Hi!

I'm still programming my little game and just wondered how to best deal with unexpected behaviour, i.e. when something fails that should work.
Well the short term to describe this is Exception Handling, but when should I use what method?

For example, if I expect my Func1 to return "true" and I check this via an if I could either throw new std::exception(...); and have to catch it somewhere or I could return NULL for the function calling that function and just pass the problem on, what the exception also does somehow.

So I would like to have some opinions about this.

Thanks,
Xaser


If something that shouldn't fail fails an exception is a good way to deal with it, for example in a xml model loader you could throw an exception if the file is of the wrong format (This allows you to pass far more information about the error than a simple return value would and the calling code could decide how to deal with the error far better than the model loader itself can (Should the error be logged ? do you need to know at what line in your code your failed call originated from ?, should you display it to the end user and if so, how should you display it ?, solving all this with just simple return codes can become extremely messy. (Take a look at the old mysql functions in php and its error handling if you want to see how bad things can be when you don't have exceptions (exceptions was added in php5)

if an error code can tell the calling function all it needs to know then you don't need (and shouldn't use) exceptions though.
[size="1"]I don't suffer from insanity, I'm enjoying every minute of it.
The voices in my head may not be real, but they have some good ideas!
Well thanks, I guess exceptions are better in my case, as they can carry much more information and distinguishing between error codes etc will just fill the code and make it less readable.

Xaser
IMHO I've found it most practical to use exceptions for truly exceptional cases only. In other words, a typical execution should never throw any exception.

For example, take the following function:
int ParseInt(char* input)


What if the input is not an integer? How should this be handled, should it throw an exception or not?
The answer depends on where you put the responsibility to check whether the input is valid or not.

1) The caller is responsible for validating input (perhaps via a companion "IsInt()" method), hence invalid input is an exceptional case, and it should throw.

2) The ParseInt method takes responsibility of validating input, and is prepared to handle anything. A better signature might then be:
bool TryParseInt(char* input, int& output)

openwar - the real-time tactical war-game platform

In C# or Java, exceptions are fine.
In C++, exceptions should never be used. Ever. At all.

In C++, exceptions should never be used. Ever. At all.
[/quote]
You go too far, sir!

More seriously, there isn't a problem using exceptions in C++. You're already using them (unless you disable them, or never allocate memory using new). They are the only way to write invariant-enforcing constructors that can fail.

But yes, if you can design your program such that it doesn't actually throw an exception then that is generally preferable. I'm curious to your reasoning about never though, Hodgman.


throw new std::exception(...);
[/quote]
In C++, throw by value and catch by const reference. You don't want to deal with ownership problems when handling an exception.
Well Thanks for all the opinions, even though I'd like to know on what you based this one.


In C# or Java, exceptions are fine.
In C++, exceptions should never be used. Ever. At all.


I have decided to deal with it like Blutzeit said. If the unexpected behaviour is non critical for the function or even could be expected somehow I will use ifs. I however I got the problem that a negative function call will indicate me that something critical is wrong, which will influence the whole algorithm then I think exceptions are the better choice.

Thanks,
Xaser

ADIT:
In C++, throw by value and catch by const reference. You don't want to deal with ownership problems when handling an exception. [/quote]

So just throw 5 or what? why?? what problems could occur?
By using "new", you dynamically allocate the exception, which is unnecessary, and just means you have to remember to catch it by pointer and delete it when done. It could also be NULL. Not nice. When you throw by value, and catch by const reference, this is handled for you.

Compare:

std::exception *make_exception()
{
// Avoid std::bad_alloc during error
return new(std::nothrow) std::exception();
}

void problem()
{
std::exception *e = make_exception();
throw e;
}

int main()
{
try
{
problem();
}
catch(const std::exception *e)
{
if(e)
{
TellTheUserSomethingWentWrong(e->what());
delete e;
}
else
{
// Something went wrong, we don't know what though.
TellTheUserSomethingWentWrong("Various problems, all malign");
}
}
}

Contrast:

void problem()
{
throw std::exception();
}

int main()
{
try
{
problem();
}
catch(const std::exception &e)
{
TellTheUserSomethingWentWrong(e.what());
}
}


Note that where C++ throws exceptions (e.g. std::bad_alloc), it throws by value, so you'd end up having a mix of catching by pointer and const reference if you try to handle these.

This topic is closed to new replies.

Advertisement