When throwing exceptions in the following auth class example is it recommended to throw a different exception for each situation to be handled, eg:
addUser(...) {
// normal database code here...
switch(TRUE) {
case ($username_exists):
throw new UserExists('Cannot create new account. Account username ' . $un . ' already exists.');
case ($email_exists):
throw new EmailExists('Cannot create new account. Account email ' . $email . ' already exists.');
}
}
//to be called externally by...
try {
$auth->adduser(...);
} catch (UserExists) {
$output = 'That username is already taken.';
} catch (EmailExists) {
$output = 'That email is already being used.';
} catch (AuthException $e) {
$output = $e->getMessage();
}
echo $output;
}
or is it recommended to throw a general “type” of exception with a unique exception code? eg…
addUser(...) {
// normal database code here...
switch(TRUE) {
case ($username_exists):
throw new AuthException('Cannot create new account. Account username ' . $un . ' already exists.', 10);
case ($email_exists):
throw new AuthException('Cannot create new account. Account email ' . $email . ' already exists.', 20);
}
}
//to be called externally by...
try {
$auth->adduser(...);
} catch (AuthException $e) {
switch($e->getCode()) {
case 10:
$output = 'That username is already taken.';
break;
case 20:
$output = 'That email is already being used.';
break;
default:
$output = $e->getMessage();
}
echo $output;
}
I ask because I’m new to exceptions and both solutions seem equally viable. Perhaps there are other solutions entirely?
Interesting side-note: I didn’t realize I was asking a “what’s your preference” question until after receiving a few answers. I anticipated a single recommended method.
I wouldn’t say one way is right and one way is wrong – and asking a “is this way recommended versus this way” can easily stir up a large pot if the question hits the right nerve in a large group.
Regarding your question specifically, both are valid and acceptable ways to throw different types of exceptions – and I’ve seen both quite frequently.
In large-scale applications in just about every language, however, I see the bottom method more often than not – and it’s also my own personal style/preference. I think that throwing a single “type” of exception,
AuthException, and specifying an exception-code is very clear and concise.If you want it to be more descriptive (from a programming standpoint), you can use an pseudo-
enum* setup for the codes to give a user-friendly description:To throw the exception with the code:
If you have an actual custom-
Exceptionclass, i.e. – youextend Exception, you can place the codes direction in the class itself:*
Enumerationsare not native to PHP, so usingconstis the easiest method (without using a 3rd-party class/plugin.