C++ Exceptions – Should One Derive/Inherit from std::exception?

cexceptions

While designing my first 'serious' C++ library, I'm asking myself:

Is it good style to derive ones exceptions from std::exception and it's offsprings?!

Even after reading

I'm still not sure. Because, besides common (but maybe not good) practice, I would assume, as a library user, that a library function would throw std::exceptions only when standard library functions failed in the library implementation, and it can't do anything about it. But still, when writing application code, for me it's very convenient, and also IMHO good looking to just throw a std::runtime_error. Also my users also can rely on the defined minimum interface, like what() or codes.

And for example, my user supplies faulty arguments, what would be more convenient, than to throw a std::invalid_argument, wouldn't it?
So combined with the yet common use of std::exception I see in others code:
Why not go even further and derive from your custom exception class (e.g. lib_foo_exception) and also from std::exception.

Thoughts?

Best Answer

All exceptions should inherit from std::exception.

Suppose, for example, I need to call ComplexOperationThatCouldFailABunchOfWays(), and I want to handle any exceptions that it could throw. If everything inherits from std::exception, this is easy. I only need a single catch block, and I have a standard interface (what()) for getting details.

try {
    ComplexOperationThatCouldFailABunchOfWays();
} catch (std::exception& e) {
    cerr << e.what() << endl;
}

If exceptions do NOT inherit from std::exception, this gets much uglier:

try {
    ComplexOperationThatCouldFailABunchOfWays();
} catch (std::exception& e) {
    cerr << e.what() << endl;
} catch (Exception& e) {
    cerr << e.Message << endl;
} catch (framework_exception& e) {
    cerr << e.Details() << endl;
}

Regarding whether to throw runtime_error or invalid_argument versus creating your own std::exception subclasses to throw: My rule of thumb is to introduce a new subclass whenever I need to handle a particular type of error differently than other errors (i.e., whenever I need a separate catch block).

  • If I introduce a new exception subclass for every conceivable type of error, even if I don't need to handle them separately, then that adds a lot of class proliferation.
  • If I reuse existing subclasses to mean something specific (i.e., if a runtime_error thrown here means something different than a generic runtime error), then I run the risk of conflicting with other uses of the existing subclass.
  • If I don't need to handle an error specifically, and if the error that I'm throwing exactly matches one of the existing standard library's errors (such as invalid_argument), then I reuse the existing class. I just don't see much benefit to adding a new class in this case. (The C++ Core Guidelines disagree with me here - they recommend always using your own classes.)

The C++ Core Guidelines have further discussion and examples.