NogDog;11034637 wrote:Of course, there are those who insist a function/method should only have one return, who would then shudder at the thought of testing for an error and immediately returning if found.
Would you care to elaborate / point to (re)sources? I have trouble coming up with any but three possible scenarios
1. test for error, return without indication => agreed, sounds bad
2. test for error, return with indication of this
3. test for error, throw exception
NogDog;11034637 wrote:
Also, depending on what you are checking for, said purists would say if it's something like validating user input, it's not an exception
And why not? Please elaborate, or point me to other (re)sources.
As I understand exceptions and their usage, it goes a little something like this:
1. when something is wrong, throw
2. if you can handle -> do so!
3. if not, log and rethrow (so the the exceptions are tiered just like the rest of the architecture and matches the same abstractions)
Let's say your code ends up doing this
$db = new PDO;
$db->query("INSERT INTO table(varchar2) VALUES('abc')");
The initial error would be a 22001 - data right truncated. Probably translated into "data too long for column 'varchar2'", which is turned into a PDO exception. Whatever the data layer receieves, it should definitely not expose pdo exceptions to the model. The best thing it could do would be to thow SomeDataLayerException which, in turn, would provide the model with enough information to, in turn, provide the view with
[b]something[/b]* the view can use to somehow give the user appropriate feedback, such as indicating the offending input field
* So what should "something" be?
What makes more sense than throwing an exception? The error could be detected in two ways. The first is "while validating input, before trying to store" and the second is "oops, something went wrong further down the chain and they let me know - by throwing". If detected by catching an underlying exception, the proper course of action would be to log the error and rethrow (its own kind of exception, not a data layer exception), so that the model might handle it. If detected during validation, throw without logging. Having two ways of letting the view know "username is too long" makes no sense. The user doesn't care who detected the problem, and thus, the view has no reason to.
Moreover, the reason you throw exceptions is so that if no point along the call chain knows how to handle the exception, the program should terminate with a big flashing "WTF!?". Not being able to create an account due to a too long username certainly seems like something a user should be informed about. If not nicely, then reasonably through an "Abnormal program termination. Unhandled exception 'Validation' with message: username too long".
And just to be clear, I'm not claiming that you should "always throw exceptions". For example, let's say someone tries to create a new user, with a too long username, by sending a POST request to your REST api. Wether you detect that during validation or you detect it due to the 22001 data right truncated error being propagated through various exceptions up the chain, I'd still expect both to end in a 400 Bad Request.
Where's the difference between that and an exception thrown by the model and caught by the view when they both reside within the same architecture?