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::exceptiondoes not mean you throw a
std::runtime_errordoes inherit from
std::exceptionin the first place, and the
what()method comes from
std::runtime_error. And you should definitely create your own exception classes instead of throwing generic exceptions such as
lib_foo_exceptionclass derives from
std::exception, the library user would catch
lib_foo_exceptionby just catching
std::exception, in addition to when he catches only the libary one. So I could also ask Should my library exception root class inherit from std::exception .
lib_foo_exception?" With inheriting from
std::exceptionyou can do it by
catch(lib_foo_exception). Without deriving from
std::exception, you would catch it if and only if, by
catch(...). It's there because the language allows for the case you're considering (and for "misbehaving" libraries), but that's not modern best practice.
catchsites, and likewise coarser transactions that model a user-end operation. If you compare it to languages which don't promote the idea of generalized catching of
std::exception&, e.g., they often have a lot more code with intermediary
try/catchblocks concerned with very specific errors, which somewhat diminishes the generality of exception-handling as it's starting to place a much stronger emphasis on manual error handling, and also on all the disparate errors that could possibly occur.