Using Exceptions

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

Post Reply
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Using Exceptions

Post 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 :)
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

Have you read all the other threads that have been on the subject of exceptions?
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Post 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
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Re: Using Exceptions

Post 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) 
{ 
   //...  
}
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: Using Exceptions

Post 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 :)
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Re: Using Exceptions

Post 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
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Post 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:
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post 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).
User avatar
johno
Forum Commoner
Posts: 36
Joined: Fri May 05, 2006 6:54 am
Location: Bratislava/Slovakia
Contact:

Post 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
User avatar
Maugrim_The_Reaper
DevNet Master
Posts: 2704
Joined: Tue Nov 02, 2004 5:43 am
Location: Ireland

Post 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.
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Post 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!');
}

?>
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

ahem... set_exception_handler()... for the lazy.
Post Reply