Quote Originally Posted by itsmeandnobodyelse View Post
I always wondered why the 'someone higher' should be able to handle a case better than the current function which made the failed call. If so, I would assume the 'someone higher' better had made the call itself.
An example I like to give is that of database transactions. Say you have a service that is responsible for creating a connection to the database. That service will choose which database to connect to, with which privileges, with which user... everything.

Once you have launched this service and all is well and good, you step into another module, the one that is responsible for actual translation of object into database queries, and then to transform the db answers back into objects. At the very end of this module, is a launch query command.

Now image this query un-unexpectedly fails, because the database is down. You can't conceivably imagine the launch query function would actually rebuild the connection, with everything from the first service. In particular, that function can't even call the service because it not only has enough information to do so (users etc.), but it can't call the service because of code dependencies.

So the function throws an exception, which travels up, all the way into the entry point of the service that asked for the transaction. THAT service will then return with a fail code, or fix the connection before trying again, or give up.

The problem with return codes is that 99% of the time, you end up writing things like this:

Code:
ReturnCode my_function()
{
    ReturnCode code = my_nested_function();
    if(code == FAILED)
        {return FAILED;}

    return SUCCESS;
}
Is that really any better? You just end up coding the same thing, but doing it manually every step of the way (And the end result is still "Just keep returning the error code until someone higher deals with it"). The worst part of this approach is that even if my_nested_function never fails, you still wrote the code for it!

In a big project (like the one I'm working on right now), each and every function has a return code. About 50% of our actual code (seriously50%) is checking return codes, but in the end, we never actually ever do anything with them, but just push them up to whoever wants to handle them. We're stuck with them because we have a ton of naked pointers, and manually managed stuff (no RAII), so we can't move to exceptions.

I don't know if you've ever had the chance to work on large scale projects that use a exception-centric and another that uses return code-centric projects. I have tried both, and I can tell you that the exceptions is not only much more robust (really, exceptions make your app much much safer), it is also several orders of magnitude easier to maintain.

Finally, exceptions make coding much faster and easier. By having the "some higher up handle it" can mean the difference between writing error handling code for the (literally) thousands of functions/objects/calls, and a single catch clause in "someone higher up".

My two cents. Cheers.