C++ Exceptions – How to Create and Enforce Contracts

cexceptions

I'm trying to convince my team lead to allow using exceptions in C++ instead of returning a bool isSuccessful or an enum with the error code. However, I can't counter this criticism of his.

Consider this library:

class OpenFileException() : public std::runtime_error {
}

void B();
void C();

/** Does blah and blah. */
void B() {
    // The developer of B() either forgot to handle C()'s exception or
    // chooses not to handle it and let it go up the stack.
    C();
};

/** Does blah blah.
 *
 * @raise OpenFileException When we failed to open the file. */
void C() {
    throw new OpenFileException();
};
  1. Consider a developer calling the B() function. He checks its documentation and sees that it returns no exceptions, so he doesn't try to catch anything. This code could crash the program in production.

  2. Consider a developer calling the C() function. He doesn't check the documentation so doesn't catch any exceptions. The call is unsafe and could crash the program in production.

But if we check for errors in this way:

void old_C(myenum &return_code);

A developer using that function will be warned by the compiler if he doesn't provide that argument, and he'd say "Aha, this returns an error code I must check for."

How can I use exceptions safely, so that there's some sort of contract?

Best Answer

This is a legitimate criticism of exceptions. They are often less visible than simple error handling such as returning a code. And there is no easy way to enforce a "contract". Part of the point is to enable you to let exceptions be caught at a higher level (if you have to catch every exception at every level, how different is it from returning an error code, anyway?). And this means that your code could be called by some other code that doesn't handle it appropriately.

Exceptions do have downsides; you have to make a case based on cost-benefit.
I found these two articles helpful: The necessity of exceptions and Everything wrong with exceptions. Also, this blog post offers opinions of many experts on exceptions, with a focus on C++. While expert opinion seems to lean in favor of exceptions, it is far from a clear consensus.

As for convincing your team lead, this might not be the right battle to pick. Especially not with legacy code. As noted in the second link above:

Exceptions cannot be propagated through any code which is not exception safe. The use of exceptions thus implies that all code in the project must be exception safe.

Adding a little bit of code which uses exceptions to a project that mainly does not is probably not going to be an improvement. Not using exceptions in otherwise well-written code is far from a catastrophic problem; it might not be a problem at all, depending on the application and which expert you ask. You have to pick your battles.

This is probably not an argument I would spend effort on--at least not until a new project is started. And even if you have a new project, is it going to use or be used by any legacy code?