# Exceptions and Return codes (yes sorry, agian).

## Recommended Posts

HexDump    233
Hi all, I have read lota of information about exceptions, lota of threads here about them and return codes, but I can´t decide what to do. It seems the best thing is to mix Exceptions and return codes, and user Exceptions only for really important errors (pretty hard to decide what are they). So, Could anyone expose its point of view, and give any example about how to use all this in correct way?. Best practices, etc... Thanks in advance, HexDump.

##### Share on other sites
darkelf2k5    286
write error-free code :)

##### Share on other sites
HexDump    233
Heheeh, you know thi is impossible :), not everything depends on the programmer.

HexDump.

rip-off    10976

##### Share on other sites
Telastyn    3777

I agree with Sit in the link that the most important thing is to be consistent. I throw a lot more in Java than in C++ for example. Personally, I don't buy into the 'Exceptions only for exceptional circumstances'. If you have an error in a function that the caller needs to know about, that's exceptional enough for me. Though that doesn't always call for an exception.

The other options aren't really great to me either. A bool usually isn't too useful and will often get ignored leading to bugs. I'll use these for something like Container.Remove(Item) where the success might be useful to know, but ignoring it won't be the end of the world.

Returning null/error-value on failure is similar, but (imo) better since the caller can't really ignore the return value since that's often what they want in the first place.

A static errno style error code sucks, and should be avoided.

A returned error code is (imo) not so good either. It leads to a lot of case statements where-ever the method is used, or a catchall "handle this error code" method which makes stuff unclear and icky. Plus it somewhat defeats the purpose of a function (take input, produce output).

But that assumes the caller needs to know about the method's failure. That isn't always the case, and (imo) should be the preferred design. If a player doesn't have permission to do something in-game for example, you can handle that within the method (perhaps with a configurable event) or just no-op and log it.

But yeah, check out those links. People far more seasoned and intelligent than I might think otherwise (and have better reasons why).

##### Share on other sites
To me, a really good time to use an exception is when you have a lot of stack unwinding to do. Cleans up the code nicely.

##### Share on other sites
HexDump    233
Hi again,

ReadTFM, mate, don´t understand what you want to mean :). Why would you do stack unwinding by yourself?

Another question that goes paralell to this question: Where should a catch go, I mean, I don´t feel like writing try/catch for every everror I want to check, do anybody know (I don´t know if this a stupid question) where catches should go? (I have read they execptions should be using for centralized processing of errors, so, there should be some key places where put them).

HexDump.

##### Share on other sites
ToohrVyk    1595
Quote:
 Original post by HexDumpAnother question that goes paralell to this question: Where should a catch go, I mean, I don´t feel like writing try/catch for every everror I want to check, do anybody know (I don´t know if this a stupid question) where catches should go?

Always place a catch statement in a place where you can handle the exception that you catch.

##### Share on other sites
Quote:
 ReadTFM, mate, don´t understand what you want to mean :). Why would you do stack unwinding by yourself?

Sometimes a failure needs to be propagated up several levels. Instead of having the three or four or whatever functions test for return codes and then return an error code themselves, it's easier to throw an exception that will jump through the stack all the way up to the top level caller.

##### Share on other sites
HexDump    233
ToohrVyk, sure you said something pretty logical for all of you, but could you put any example? it doesn´t need to be code, just a practical example, because I think put a catch in every try won´t be the right way to go.

HexDUmp.

##### Share on other sites
ToohrVyk    1595
Consider a function which reads an object from a network connection, and returns that object. If the network connection dies (throwing the relevant kind of timeout or EOT exception), there's nothing the function could do to return a valid object. Thus, the function must not catch the exception, and simply let it move up the call stack instead.

On the other hand, if the function is about a server connecting players to the game, then there's a pretty simple thing to be done when the connection breaks down: remove the player from the game, and possibly log the issue or broadcast a relevant message. Thus, the function should catch the exception, because it can solve the issue.

##### Share on other sites
Antheus    2409
RAII is another approach that mandates exceptions.
NonNegativeNumber p(user_input);

If user enters -18, p cannot be created, exception is thrown, and execution from then on is impossible.

While there are alternatives, the error handling here is robust and transparent.

One might however opt for allowing invalid input, but the question remains - what is a good replacement? We cannot accept negative number, but we need to replace it with a default value.

But in this case, we have removed the exceptional condition and changed the flow. Exceptions are one tool that is used to enforce logical correctness of application.

##### Share on other sites
Antheus    2409
Quote:
 Personally, I would look into replacing that with a value that clamps the range to min/max (thus values below/above become min/max) and a method to accept user input (doing logic if invalid, or just letting the clamped value do its thing). That sort of separation of responsibility is often available in situations that arise as possible exception/error cases.

As I said, you can change the original problem.

My example was more focused on code-path if you use invariants.

NonNegativeNumber p(user_input);...// p is valid, non-negative

Sometimes, changing the problem is viable, sometimes it's not.

A more realistic example:
void send(SomeMessage &msg){  Buffer b(500); <- allocation succeeded  Serializer s(msg, b); <- serialization of msg into b succeeded  socket->sendto(s->contents, s->size); <- s is valid}void notifyClients(){  StateChangeMessage msg( who, 17, 0, "new_state", 0); <- parameters are correct  send( msg ); <- msg is valid}...try{  ...  notifyClients();  ...  } catch ( ??? ) {  // A *lot* of things can go wrong  // but if we fail, we can't do much}

Many things can go wrong - but code line by line establishes invariants, allowing you to bypass many/most/all user-level checks and assertions.

With error codes, this would result in a very large number of tests, error reports and conditions, which in case of RAII are conveniently abstracted and encapsulated, allowing for a much more straight-forward code.

But whichever approach you choose, you impose one coding style, hopefully a consistent one. In case of RAII and proper encapsulation, you can perform almost all error checking within implementation of classes themselves, thereby staying very OO oriented.

##### Share on other sites
Telastyn    3777
Heh, sorry. Antheus quoted my post which I deleted before he could reply since it was nitpicky and focusing on the example rather than the assertion regarding exceptions + RAII (which is correct)