Just because you can stick your hand in a blender, that doesn’t mean you should. Similarly, you can throw
anything, but that doesn’t mean you should throw
something that’s not derived at some level from
std::exception
.
If you can’t find an existing exception type that suitably conveys what you need to convey, then you should extend std::exception
to
create one.
Specifically, part of the point of throwing exceptions is to communicate about the conditions of the error, but primitives have far less ability to
communicate meaningfully than exception
s. And, the creation of some other object type could itself throw
an exception,
resulting in program termination.
Further, catch
ing non-exception types is painful and fraught with the potential for (further) error.
Noncompliant code example
throw 42; // Noncompliant
throw "Invalid negative index."; // Noncompliant
throw std::string("Permission denied"); // Noncompliant
throw nullptr; // Noncompliant
Compliant solution
throw std::domain_error("User ID not found.");
throw std::out_of_range("Invalid negative index.");
throw std::system_error(EACCES, std::system_category());
throw std::invalid_argument("Unexpected null 'user_id' argument.");