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::exception
s 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?
std::exception
does not mean you throw astd::exception
. Also,std::runtime_error
does inherit fromstd::exception
in the first place, and thewhat()
method comes fromstd::exception
, notstd::runtime_error
. And you should definitely create your own exception classes instead of throwing generic exceptions such asstd::runtime_error
.lib_foo_exception
class derives fromstd::exception
, the library user would catchlib_foo_exception
by just catchingstd::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 fromstd::exception
you can do it bycatch(std::exception)
OR bycatch(lib_foo_exception)
. Without deriving fromstd::exception
, you would catch it if and only if, bycatch(lib_foo_exception)
.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.catch
sites, 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 ofstd::exception&
, e.g., they often have a lot more code with intermediarytry/catch
blocks 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.