Page 1 of 1

Using Exceptions

Posted: Wed Nov 15, 2006 8:35 pm
by alex.barylski
Without going into definitions of what and when an exception should be used (and ignoring bad design) when, where and how do you utilize exception support in PHP 5?

For instance...assume you've developed a DB abstraction layer which throws exceptions when the SQL statement is invalid or mysql_query otherwise fails. You don't wish to have redundant error checking sprinkled througout your code base, so do you use a single catch all approach?

class.bdal.php

Code: Select all

class Project_Dbal{

  // This function is called by Project_User methods
  function querySql($sql)
  {
    $res = mysql_query($sql);
    if(!$res) throw MySqlQueryException('Malformed SQL statement');
  }
}
index.php - single application entry point

Code: Select all

include 'classes/class.dbal.php';
include 'classes/class.user.php';
include 'classes/class.boot.php';

try{
  // Highlevel catch all
  $obj = new Project_User();
  $obj->returnUser($pkid);
}
catch($e){
  // Check $e 'type' and use a switch to handle various exceptions?
  echo 'Highest level error handler';
}
If you differ from the above explain why...but practically not just because your repeating something verbatim from a book.

Cheers :)

Posted: Wed Nov 15, 2006 8:43 pm
by feyd
Have you read all the other threads that have been on the subject of exceptions?

Posted: Wed Nov 15, 2006 9:08 pm
by alex.barylski
feyd wrote:Have you read all the other threads that have been on the subject of exceptions?
Off topic: Why yes...yes sir I have...infact...apparently I've even contributed to a few threads in regards to exceptions... :P

Re: Using Exceptions

Posted: Wed Nov 15, 2006 10:09 pm
by John Cartwright
Hockey wrote:

Code: Select all

try{
  // Highlevel catch all
  $obj = new Project_User();
  $obj->returnUser($pkid);
}
catch($e){
  // Check $e 'type' and use a switch to handle various exceptions?
  echo 'Highest level error handler';
}
Whats the point of catching if you arn't trying to recover your fatal error? I'sn't that the whole point?
...You don't wish to have redundant error checking sprinkled througout your code base
And what exactly do you mean having sprinkled error checking throughout the code base?
so do you use a single catch all approach?
Each throw should have it's own catch, to try (although you may just want to spit the error) and recover from the error.

Code: Select all

try 
{
   if ($foobar) {
      throw new FooBarException('food');
   }

   if ($barfoo) {
      throw new BarFooException('bard');
   }
} catch (FooBarException $e) 
{ 
   $error = new log();
   $error->setMessage($e->getMessage());
   $error->save();

   //attempt to fix error

} catch (BarFooException $e) 
{ 
   //...  
}

Re: Using Exceptions

Posted: Wed Nov 15, 2006 11:16 pm
by alex.barylski
Thanks for the reply... :)

It appears as though we have different understandings of how and when to use exceptions...

I'll be honest...for whatever reason exceptions in PHP don't seem to satisfy me...unlike in MFC when dealing with Windows...if you provide a Window operation an invalid handle or a plethora of other things...an exception can be used - sometimes to even recover...Same goes with Javascript...when accessing the DOM before it's initialized(fully loaded)...exceptions can be caught and sometimes prevent fatal errors from occuring...but in PHP...I'd like to see some examples...like when a database query fails...it's something you can't typically recover from completely...so an exception I can see making sense...

Just the way applications are constructed I guess...it's making it awkward to conceptualize all occurances of exceptions...in PHP's context

I can't say I agree with your statement that every throw should have its own try-catch block...thats an example of over zealous use IMHO...except when absolutely needed - note the exception keyword :)

p.s-tired...write more later...need food + drink :)

Cheers :)

Re: Using Exceptions

Posted: Thu Nov 16, 2006 12:01 am
by John Cartwright
Hockey wrote:I can't say I agree with your statement that every throw should have its own try-catch block...thats an example of over zealous use IMHO...except when absolutely needed - note the exception keyword :)
Then why bother using try catch in the first place? An exception isn't unnecessarily used only to recover from fatal errors, this is just a uniform way of handling system errors.

Your example of using exceptions with a query call isn't quite a good example for try catch scenario. In that case I would simply throw the exception.

Read this, then if you want to continue then we shall http://devzone.zend.com/node/view/id/679

Posted: Thu Nov 16, 2006 12:47 am
by alex.barylski
While I appreciate the link (couldn't find one very good dedicated to PHP) I'm not sure what you meant by that :P

Just what are you implying mr.? 8) just kidding

I have read countless articles and even entire books which had a strong focus on exceptions...both in use and in best practice and so on...that article (admiitedly I only skimmed it) didn't really address my question per se...as the question is more best practice oriented (at least that was my intent) not real world use - whether it's practical or not.

I'll read it in the morning and get back to you...right now i'm bushed :D

Thanks for the link

Have a good night...

p.s-Aren't you in the big smoke? isn't it like 3am there? what are you still doing up? :wink:

Posted: Thu Nov 16, 2006 12:56 am
by Chris Corbyn
I don't only throw exceptions on fatal errors. Exceptions also provide useful information about non-fatal errors if used correctly. Equally, I don't use tiny little try/catch statements.... there's not really an issue I see with having a block of logic ctaching multiple types of exception, provided that none of those exceptions are recoverable. If you look at Java you'd be overwhelmed by the amount of exceptions you'll be working with. They even force you to use try/catch when no exceptions are throw, just in case one is thrown (when declared to be thrown).

Posted: Thu Nov 16, 2006 3:15 am
by johno
First of all the is a golden rule for exceptions. Throw an exception only if you can't handle the error in current scope. But wait! This does not hold the other way, so don't throw exceptions whenever you can't handle errors in current scope. You can also somehow return some null value and fail silently, right?

From my experience I don't use exceptions very much. But if I do It mostly depends on two things:

1) If I need to distinguish between more than one type of error. Say a Account class may throw UnsufficientFundsException or AccountBlockedException on sendFunds() method. But this can also end with breaking up class because of "class-is-doing-too-much" smell.

2) If there starts to emerge a chain of same error checking through multiple layers without actually handling them. This is the case where you can't handle error in current scope and also not in the parent scope. Throwing an exception and catching it in layer which can actually handle it will greatly reduce this chaining.

There is another rule that says: Don't use exceptions for normal program flow. Well yes, this makes sense since exceptions are some sort of OO goto statements. But the important thing is how you define a normal flow. In my little framework I use exceptions for page redirecting. A pure "exceptionist" would scream loud, that redirecting is a normal flow. Well yes it is from the application point of view. But my controllers (some sort of reusable widgets) have only a render() method that returns HTML fragments. So normal flow is only to return a HTML fragment, a redirect is a "exception" that my controller cannot handle. The redirect exception is handled at top level in a catch block which creates a redirecting HTTP response and send it into the wild world web. ;-)

As stupid as this may seem from a purist point of view, it works great and simplifies my code greatly. I can also add more types of special exceptions. Maybe throwing a page not found exception which will be always handled at top level and return a fancy styled 404 page.

And finally closing with a useful link. http://c2.com/cgi/wiki?CategoryException

Posted: Thu Nov 16, 2006 3:33 am
by Maugrim_The_Reaper
I always throw exceptions. Whether they are caught or not is up to the client code ;).

For PHP at least an uncaught exception with a descriptive Exception subclass name has a lot of value. If it's non-recoverable, you can dump the contents to a log with the whole trace stack and fail silently (or if you use an exception handler redirect elsewhere).

I generally try to avoid using exceptions to control program flow. Not saying it's wrong or anything - just a personal preference.

Posted: Thu Nov 16, 2006 3:44 am
by Jenk
I always catch, I don't want PHP printing filenames and what not on users browsers.

Exceptions are used when, funnily enough, and exceptional result is met - i.e. one that differs from the expected result.

In PHP this may seem redundant because we have loose type returns, but in Java where we must declare the return type before it is even returned, we result to throwing an exception. This behaviour has simply made it's way into PHP because of demand, and it removes the need to have loads of if()'s in your code, when all you need is a catch() for an exceptional circumstance.

Code: Select all

<?php

public function getInteger()
{
    // blah..

    throw new Exception('There is no Integer to return!');
}

?>

Posted: Thu Nov 16, 2006 6:43 am
by feyd
ahem... set_exception_handler()... for the lazy.