Quantcast
Channel: Squirrel Hacker » Password
Viewing all articles
Browse latest Browse all 11

Exceptions Are Not For Flow Control

$
0
0

When I saw this post on Better Error Handling, while there is nothing horribly horribly wrong with it I couldn’t help thinking that he has gone past proper error handling. Exceptions are for exceptional cases, hence the name. They should not to be used for flow control, or for things that could occur normally like a user failing to login.

This is because almost all function calls are basically a question:

  • Did the user enter the correct information to login? Yes, No
  • Did the database query return data? Here is the data array, here is an empty array.
  • Is the data that the user entered valid? Yes, No.

Within these functions, you can pass an error to the next screen, view, wherever you are returning to because the function failed to produce a positive result.

Things that are exceptional cases would be something similar to the following. In these cases, you cannot continue because the assumptions made by your code were not fulfilled.

  • A malformed query on the database (MalformedDatabaseQueryException)
  • no connection to the database (DatabaseMissingException)
  • the database timed out (DatabaseWentAwayException)
  • A file is deleted while you are reading/writing it (FileWentAwayException)
  • trying to call a function that takes an integer by passing it a string, object or array (InvalidDataTypeException)

The problem with using exceptions for flow control is that you will inevitably end up with something like this if you want to handle each exception individually:

<?php
try{
	$user->login();
} catch(InvalidDataException $e){
	//handle invalid data exception
}catch(CouldNotLogInException $e){
	//handle could not login
}catch(DatabaseException $e){
	//handle database exception
}

Or something like this if you don’t want to check all possible errors:

 
<?php
try{
	$user->login();
} catch(Exception $e){
	//handle exception
}

The problem with the second one is that now you are treating all exceptions the same way regardless of their actual severity.

Or, if you are validating data:

try{
	validateUsername($_POST['username']);
} catch(Exception $e){
	//handle exception
}
 
try{
	validatePassword($_POST['password']);
} catch(Exception $e){
	//handle exception
}
 
try{
	validateDateOfBirth($_POST['birthday']);
} catch(Exception $e){
	//handle exception
}
 
try{
	validateTwitterAccount($_POST['twitter_account']);
} catch(Exception $e){
	//handle exception
}
//and so on...

Or if you are lazy:

try{
	validateUsername($_POST['username']);
	validatePassword($_POST['password']);
	validateDateOfBirth($_POST['birthday']);
	validateTwitterAccount($_POST['twitter_account']);
} catch(Exception $e){
	//handle exception
}

But then you can only show the user the first thing that failed. Which is not good from a usability perspective because they might have messed up everything after the username, and would then have to submit the form 4 times.

Instead you could do this:

/**
 * Show the fatal error page when an exception occurs
 * @var Exception $exception;
 */
function myExceptionHandler($exception){
	displayErrorPage($exception->getMessage());
}
set_exception_handler('myExceptionHandler');
 
$u = new user();
$u->username = $_POST['username'];
$u->password = $_POST['password'];
$u->birthday = $_POST['birthday'];
$u->twitter_account = $_POST['twitter_account'];
if($u->save()){
	//continue to the next page with a confirmation message
} else {
	//show the user the errors that occurred on the page they just came from
}

Which is a much nicer alternative.

flattr this!


Viewing all articles
Browse latest Browse all 11

Latest Images

Trending Articles





Latest Images