Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should I handle expected errors? eg. "username already exists"

I am struggling to understand how I should design the error handling parts of my code. I recently asked a similar question about how I should go about returning server error codes to the user, eg. 404 errors. I learnt that I should handle the error from within the current part of the application; seem's simple enough.

However, what should I do when I can't handle the error from the current link in the chain? For example, I may have a class that is used to manage authentication. One of it's methods could be createUser($username, $password). Edit: This method will return a user id or user object. Within that function, I need to determine if the username already exists. If this is true, how should I alert the calling code about this? Returning null instead of a user object is one way. But how do I then know what caused the error?

How should I handle errors in such a way that calling code can easily find out what caused the error? Is there a design pattern commonly used for this kind of situation?

Edit: I forgot to mention: I am using PHP.


Solved: While many people argue that exceptions should not be used in this situation, I have come to the conclusion that it is the best solution.

Firstly, there is no simple, elegant alternative to exceptions. (I recon that it is not possible without a system built into the language... exceptions are already built in.)

Secondly, in response to the "exceptions should only be used for exceptional situations, and this is not one" argument: "When I call getFoo(), I actually expect to get a Foo. If I don't get it, it's by definition an exceptional event." (via, pkainulainen)

like image 531
Peter Horne Avatar asked May 11 '10 20:05

Peter Horne


1 Answers

There are a few common patterns:

1. Throw an exception.

2. Return NULL or FALSE and set a passed in reference to an error. E.g.

function createUser($user, $password, &$error)
{
      //...
      // You could use any type of object here.  This is just a simple example.
      if(uniqueKeyFailure)
      {
          $error = new UserAlreadyExists();
          return NULL;
      }
      //..
}

It could be called like:

$userCreateError = NULL;
$res = createUser($user, $pass, $userCreateError);
if($res === NULL)
{
  // do something with $userCreateError
}

3. Return NULL or FALSE and provide a get last error (e.g. curl_error).

I would recommend 1 or 2. The main reason people avoid exceptions for "unexceptional" errors like user input is performance. There is a fair amount of discussion on this, such as Performance of try-catch in php.

I do not recommend 3 as it is not reentrant.

like image 100
Matthew Flaschen Avatar answered Sep 19 '22 17:09

Matthew Flaschen