Currently within our API we have our own exception-type MyException
which does not (neither directly nor indirectly) inherit from std::exception
or any other type:
class MyException {
public:
MyException(std::string const& message);
std::string const& GetErrorMessage() const;
private:
//...stuff, e.g. like the error-message.
};
To our customers (and our own developers ) this leads the burden of always adding at least two catch-handler to a try-block:
try {
SomeLibraryFunction();
}
catch (MyException const& e) { std::cerr << e.GetErrorMessage(); }
catch (std::exception const& e) { std::cerr << e.what(); }
To reduce the number of catch-handler I would like to add inheritance from std::exception
. But the problem with that is that it will "break" existing code. Namely the compiler will choose a different catch-handler than it did before:
try {
SomeOtherLibraryFunction();
}
catch(std::exception const& e) { std::cerr << "STD-EX"; }
catch(MyException const& e)
{
std::cerr << "LIBRARY-EX";
ExecuteMandatoryCodeWhenMyExceptionGetsThrown(e);
}
As soon as MyException
inherits from std::exception
the second catch-handler will never be reached. The reason for that is stated here:
When an exception of type E is thrown by any statement in compound-statement, it is matched against the types of the formal parameters T of each catch-clause in handler-seq, in the order in which the catch clauses are listed.
Is there a way that the compiler will take the catch-clause that is the best match instead of taking the first match? Or any other way to achieve the inheritance from std::exception
without changing which catch-handler will be called?
The safest way is to change the exception type to a new type in this case, e.g. MyExceptionV2
, educate people that it is much better, and that MyException
is going to be deprecated eventually. Then give them time to upgrade their catch blocks to use your new type and remove the extra catch blocks. Then deprecate it in the next version, then remove MyException
in the later version.