Reputation: 5882
What are the best practices for an object that can throw an exception for many reasons?
For example if I have an assembler object that has its own exception type which derives from std::exception I can just set the message for what() to return. So I might do:
throw Asm::Exception("Duplicated function name");
throw Asm::Exception("Unknown instruction");
throw Asm::Exception("Wrong number of arguments");
But I'm wondering if:
throw Asm::DuplicateFunctionNameException();
throw Asm::UnknownInstructionException();
throw Asm::WrongNumberOfArgumentsException();
Is better? But I fear this could lead to many small objects that are essentially doing the same thing?
Upvotes: 1
Views: 73
Reputation: 179779
throw Asm::Exception("Wrong number of arguments")
already shows the problem, really. That exception should have the function name, actual arguments and expected arguments. Most exceptions won't need those fields, though. Logically, that means Asm::ArgCountException
is a unique type.
Upvotes: 1
Reputation: 227390
There is no "better" or "worse" approach. In fact, the two concepts are quite orthogonal. It really depends entirely on the desired functionality. You should choose depending on the answer to this question:
Do I need to be able to take different actions depending on the type of error throwing an exception?
If the answer is yes, then you're better off with different exception types:
try {
// stuff
} catch (Asm::DuplicateFunctionNameException& e) {
foo();
e.foo();
} catch (Asm::UnknownInstructionException& e) {
bar();
e.bar();
} catch (Asm::WrongNumberOfArgumentsException& e) {
baz();
e.baz();
}
Also note that each type of exception here could have members related to that particular error type.
If the answer is no, then you're OK with one type. Note that having different types doesn't prevent you from using different messages too.
Upvotes: 4