Jump to content

When To Use Try-Catch Exceptions


Buchead

Recommended Posts

Apologies if this isn't the right place for this but have a query about try-catch and when to use it. Different articles I've read all say different things.

 

Should they be used when a class object is created, whilst some articles say you should throw an exception whenever a calculation is attempted and something goes wrong (such as invalid option).

 

On the other hand, some code I've seen pass true or false back from a calculation based upon the result.

 

I appreciate there's no hard or fast rules and it may be down to personal preferences, but are there any rough guidelines to follow? Are there any articles or books that are worth reading that could help someone new to php5 understand it a little better.

 

Many thanks.

Link to comment
Share on other sites

I tend to use try-catch a lot, it's very sexy but I mostly use them for when I'm working with PDO. Returning true/false can be very handy too but it depends on what for, I mean for something like empty() it is beneficial and it makes a lot of sense. Where as seeing that same function throwing an Exception, that would just raise a WTF in my mind.

 

Some functions throw specific errors, especially when it comes to libraries. For instance, coming back to PDO - if a query failed then it would be nice to know what went wrong other than receiving false so an PDOException can be thrown and you then have the actual error message. It really comes down to personal preference as to if you use Exceptions or not.

 

Take a look at the following example, would be used for like a form validation.


// This function will check if the username is in correct format
// Then it will check if it exists.
function isValidUsername ( $uname )
{
   if ( preg_match ( "/^[a-zA-Z0-9]+$/" ) )
   {
       return 1;
   }

   $query = mysql_query ( "SELECT COUNT(*) as num FROM users WHERE username = '$uname'" );

   $row = mysql_fetch_assoc ( $query );

   if ( $row [ 'num' ] > 0 )
   {
       return 2;
   }

   return 0;
}


if ( isset ( $_POST [ 'submit' ] ) )
{
   $res = isValidUsername ( $_POST [ 'username' ] );

   switch ( $res )
   {
       case 1:
           echo 'The entered username contains invalid characters.';
           break;

       case 2:
           echo 'The entered username is already taken.';
           break;

       default:
           echo 'The entered username is valid.';
           break;
   }
}

 

You can see that the above is lengthy, and to me looks ugly. Now lets take a look at it with Exceptions.

 


// This function will check if the username is in correct format
// Then it will check if it exists.
function isValidUsername ( $uname )
{
   if ( ! preg_match ( "/^[a-zA-Z0-9]+$/" ) )
   {
       throw new Exception ( "The entered username contains invalid characters." );
   }

   $query = mysql_query ( "SELECT COUNT(*) as num FROM users WHERE username = '$uname'" );

   $row = mysql_fetch_assoc ( $query );

   if ( $row [ 'num' ] > 0 )
   {
       throw new Exception ( "The entered username is already taken." );
   }
}

if ( isset ( $_POST [ 'submit' ] ) )
{
   try
   {
       $res = isValidUsername ( $_POST [ 'username' ] );

       echo 'The entered username is valid.';
   }
   catch ( Exception $e )
   {
       echo $e -> getMessage ( );
   }
}

 

I personally think the Exception example is a much better alternative. You will find libraries that would do a similar thing, where the library itself contains the errors (such as PDO for example). Some people may think Form Validation with Exceptions a little over the top, but I personally like it.

 

However, I would say that whether you use them or not is all down to personal preference however if the library you are using does throw Exceptions, then I would take advantage of the try-catch.

Link to comment
Share on other sites

A more sensible approach to the "Non exception" example you gave would be using an error function/log, and using "return false" instead of a numbered error code you have to decode.

 

Something like this, in other words:

<?php

// Then it will check if it exists.
function isValidUsername ($uname) {
   if (!preg_match ("/^[a-zA-Z0-9]+$/")) {
       log_error ("The entered username contains invalid characters.");
       return false;
   }

   $query = mysql_query ("SELECT COUNT(*) as num FROM users WHERE username = '$uname'");
   $row = mysql_fetch_assoc ($query);

   if ($row['num'] > 0) {
       log_error ("The entered username is already taken.");
       return false;
   }

   return true;
}

if (isset ($_POST['submit'])) {
   if (!isValidUsername ($_POST['username'])) {
       echo "Error occurred: " . read_error ();
   } else {
       echo 'The entered username is valid.';
   }
}

You might want to use the trigger_error () function with a custom error handler in this case though, that way you get different levels of error messages. Something which you can leverage when it comes to how to handle them, just like with Exceptions.

Edited by Christian F.
Link to comment
Share on other sites

Yes, definitely. Form validation is expected to fail at least some times, and failure in validating the input created by the user is not an exceptional state. I would even go as far as to say that it isn't even an error state, but a completely normal and expected state for any application accepting user-input.

 

Having the database server suddenly disappear mid-query, however, now that's an exception. :P

Link to comment
Share on other sites

Exceptions are generally for what you might consider an "unusual circumstance" (ie, exception to the general rule/expectations) or for validation issues that are likely caused by bad programming (ie, not normal form validation typically).

 

Some samples of when to use an exception:

- If you run a DB query, and the connection to the DB server has been severed, you might throw an exception. The general expectation is that a connection is established

- If you try to pass NULL to a function that expects an Object, you might throw an exception. The programmer should be testing for this case.

 

 

Some samples of when NOT to use an exception (IMO):

- When validating posted form data.

- When testing for a specific condition (ie a file_exists or isSomething like function).

 

 

When you start to use exceptions you can get a better feel for when they are and aren't appropriate. Also using a language that handles most all of it's errors via exceptions and seeing what it does can help as well. C# or Java would be good for this.

 

Regarding not using them for form validation, the reason I say that is because generally speaking you'd want to provide the end user with some details as to what exactly is wrong. If you validate each field by throwing exceptions this means you will likely either only have one message to show, or you need several try/catch blocks which results in some messy code. Simple true/false returning functions make this nicer, plus they also generally fall under then 'checking a specific condition' area.

 

This of course is all opinion. There is not any definitive "Here's when you do, Here's when you don't" guide to exceptions. You'll have to get a feel for them yourself and decide when you think an exception is appropriate vs just a true/false return value.

 

 

Link to comment
Share on other sites

Thank you all for the responses. After seeming some code that had exceptions where simple validations were being performed (such as checking for specific characters in a string) they threw an exception when I thought simply returning true or false would suffice.

 

Needless to say I have soo much still to learn and understand!

Link to comment
Share on other sites

I'm in agreement with Kicken - using exceptions for something such as an invalid username is clunky at best. There should be a distinction between a "system error" one that prevents the script from completing and a "user error" - script can complete but there are errors to display to the user. But, since the OP specifically mentioned using classes I'd like to offer a suggestion of how I like to handle user errors within a function.

 

I'll typically create an $error property for a class. Then if there are any user type errors within any of the methods I will simply set an appropriate error message in that property and return false from the method.

 

class user_class
{
   public $error;

   public function isValidUsername($uname)
   {
    if (!preg_match("/^[a-zA-Z0-9]+$/" ))
    {
	    $this->error = "The entered username contains invalid characters.";
	    return false;
    }

    $query = mysql_query("SELECT COUNT(*) as num FROM users WHERE username = '$uname'");
    $user_count = mysql_result($query, 0);
    if ($user_count>0)
    {
	    $this->error = "The entered username is already taken.";
	    return false;
    }

    return true;
   }
}



if (isset($_POST['username']))
{
   $userObj = new user_class();
   if(!$userObj->isValidUsername(($_POST['username']))
   {
    echo $userObj->error;
   }
   else
   {
    echo 'The entered username is valid.';
   }
}

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.