SitePoint Sponsor

User Tag List

Results 1 to 15 of 15
  1. #1
    Employed Again Viflux's Avatar
    Join Date
    May 2003
    Location
    London, On.
    Posts
    1,127
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Exceptions vs Errors

    When talking PHP, is there any benefit in using the new exception handling features of PHP 5 over the tried and tested methods of error handling?

    In all my projects thus far, I've used a custom error handler that performs as well as I could want.

    However, I've been doing some Java work for the first time in a while, and it got me to wondering whether I should try implementing exceptions in some of my PHP code.

    Personally, I can't see how a good exception handler can outperform a good error handler, but I'm hoping some of the guru's here can enlighten me.

  2. #2
    SitePoint Zealot stdlist's Avatar
    Join Date
    Sep 2004
    Location
    Corvallis, OR, USA
    Posts
    128
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Both have good and bad points and I tend to implement both. I like the ability to catch an exception to locally and deal with it. However, since there is so many things outside of our control that are throwing errors you must cover this as well.

  3. #3
    SitePoint Guru dbevfat's Avatar
    Join Date
    Dec 2004
    Location
    ljubljana, slovenia
    Posts
    684
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi, I tend to go with exceptions, was very glad to see them in PHP5, I missed this kind of power with error handling.

    Exceptions are very powerful, since they stop execution and exit out of the current scope. If they're caugth, they can be handled, otherwise the application stops. You can ignore errors, and nothing will happen, which is wrong when a critical error occurs.

    Another thing is very good: you don't have to pollute the return values of your functions and you don't have to verify results of your functions for occurence of an error (I really hate that in PEAR).

    If you execute some code many levels deep (in terms of function/methods calls) and you throw an error/exception, you get to another problem with errors. Catching errors/exceptions is important, and you should always think carefully which code does it, and how does it handle it. If you throw an exception some levels deep in the execution stack, you must make sure that every function/method involved (that is not supposed to catch it), only receives it and passes it out, so it actually reaches the code that handles it. This is very important, very hard to handle with errors and very easy with exceptions.

    Regards

  4. #4
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The good things about exceptions are

    1. Scope. They're thrown in current scope, so the code that caused an exception has a chance to handle it properly. With global error handler the only real option you have is to log an error and stop the whole application.

    2. OOP. Exceptions are objects with all advantages.

    The bad news are that bultin php functions don't throw any exceptions. That means you have to write a code to convert "errors" into exceptions:

    PHP Code:
    class PhpError extends Exception {
        public function 
    __construct() {
            list(
                
    $this->code,
                
    $this->message,
                
    $this->file,
                
    $this->line) = func_get_args();
        }
    }

    set_error_handler(create_function(
        
    '$errno, $errstr, $errfile, $errline',
        
    'throw new PhpError($errno, $errstr, $errfile, $errline);'
    ));


    try {
        
    fopen("not really""r");
    } catch (
    Exception $e) {
        print 
    "Exception: " $e->getMessage();


  5. #5
    Resident Java Hater
    Join Date
    Jul 2004
    Location
    Gerodieville Central, UK
    Posts
    446
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    SEH has it's pros and cons. I do tend to sway towards using it in PHP5, where as in a language like C++ I would avoid it as much as possible.

    As the name suggests, Exceptions should only be thrown in a exceptional cicumstances. Do not over use them. Ideally, catch them as soon as you can when you are dealling recover plans. However, many times I won't bother wrapping try / catch round exceptions that are thrown in truely rare cases, where an error message is needed, as uncagtht exceptions do provide valueable debug info. However, you have to be careful with security risks when doing this, and I wouldn't recommend not catching exception, dispite the fact I do leave a number of exceptions uncaght.

    Exceptions are there to safe repetive code, look at how C++ changed operator new to use this instead of return NULL. This is a good use for exceptions, as it's rare for memory not to be allocated (normally the OS can intercept this, page some data, and maybe increase the swap file size).

    On the other hand exceptions have risks ...

    try {
    $fh = fopen('test.csv', 'rb');
    flock($fh, LOCK_EX);
    $test = $fread($fh, 32768);
    throw new Exception();
    flock($fh, LOCK_UN);
    fclose($fh);
    } catch (Exception $e) {
    // Blah, file not closed
    }

    Here the file doesn't get closed. This is probably OK in many cases, but you may want to open the file and write to it befroe the request ends. This is worst with persistent DB connections if you forget to unlock tables etc. This is why C++ coders also avoid exceptions as pointers may not get deleted if you don't think about your design and us something like a shared/scoped smart pointer to make your code "exception safe".

    returning errors by value is best where you don't have exceptional circumstances

  6. #6
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Regarding the last example, that's what the "finally" clause was invented for. Unfortunately, php lacks "finally"...

  7. #7
    SitePoint Guru dbevfat's Avatar
    Join Date
    Dec 2004
    Location
    ljubljana, slovenia
    Posts
    684
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by MiiJaySung
    On the other hand exceptions have risks ...

    try {
    $fh = fopen('test.csv', 'rb');
    flock($fh, LOCK_EX);
    $test = $fread($fh, 32768);
    throw new Exception();
    flock($fh, LOCK_UN);
    fclose($fh);
    } catch (Exception $e) {
    // Blah, file not closed
    }

    Here the file doesn't get closed. This is probably OK in many cases, but you may want to open the file and write to it befroe the request ends.
    I think this is not a good example of using exceptions. The file closing code should be out of the try-catch block, since it has to be executed in any case (if the file is open) and it doesn't throw an exception. I'd also put the fopen() part outside the try-catch block. That way, I'd be sure that the file gets opened and closed, no matter what happens in the "risky" part of the code.

  8. #8
    SitePoint Guru BerislavLopac's Avatar
    Join Date
    Sep 2004
    Location
    Zagreb, Croatia
    Posts
    830
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by stereofrog
    Regarding the last example, that's what the "finally" clause was invented for. Unfortunately, php lacks "finally"...
    Nor does it need it. Everything coming after the last catch block to the end of the script gets executed.

  9. #9
    SitePoint Guru dbevfat's Avatar
    Join Date
    Dec 2004
    Location
    ljubljana, slovenia
    Posts
    684
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by stereofrog
    Regarding the last example, that's what the "finally" clause was invented for. Unfortunately, php lacks "finally"...
    I agree. I used to program in Delphi and I very much miss the "finally" block.

  10. #10
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    BerislavLopac

    "Finally" is not that is executed "after" try/catch block, it's executed "within". The purpose of finally is to run some code no matter what "catch" did, even if this was "return" or "exit". Consider the following:

    Code:
    try {
       allocate_resource() // may throw an exception
       process_resource() // may throw an exception
    } catch(Exception e) {
        return false
    }
    free_resource()
    do_something_else()
    here, if an exception occurs, the resource doesn't get freed. The correct way would be
    Code:
    try {
       allocate_resource() // may throw an exception
       process_resource() // may throw an exception
    } catch(Exception e) {
        return false
    } finally {
       // always do this
       free_resource()
    }
    do_something_else()

  11. #11
    SitePoint Guru BerislavLopac's Avatar
    Join Date
    Sep 2004
    Location
    Zagreb, Croatia
    Posts
    830
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'm not sure that I understand what you're saying. If the function returned (in catch block), when would the finally block be performed? Just before the return? Or regardless of return? The latter seems to me quite contrary to the way how PHP works.

  12. #12
    SitePoint Wizard Ren's Avatar
    Join Date
    Aug 2003
    Location
    UK
    Posts
    1,060
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I find this is where destructors come in handy.

    PHP Code:
    class Resource
    {
        function 
    __construct() { }
        function 
    free() { echo __METHOD__"\n"; }
        function 
    __destruct() { $this->free(); }
    }

    function 
    doSomething()
    {
        try
        {
            
    $resource = new Resource();
            throw new 
    Exception();
        }
        catch(
    Exception $exception)
        {
            throw 
    $exception;
        }
    }

        echo 
    'Calling doSomething..'"\n";
        try {
            
    doSomething();
        }
        catch (
    Exception $e)
        {
        }

        echo 
    'Called doSomething..'"\n"
    As soon as $resource falls out of scope in doSomething() its destructor is called.

  13. #13
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by BerislavLopac
    I'm not sure that I understand what you're saying. If the function returned (in catch block), when would the finally block be performed? Just before the return? Or regardless of return? The latter seems to me quite contrary to the way how PHP works.
    It will be executed before catch block. That's the way "finally" (or "ensure" if you like it more ) work.

    Ren, destructors are definitely handy, but finalization isn't always as simple as just destroying some object. I have a strong hope someone at Zend can implement "finally" in next releases (ruby's "retry" and "else" would be nice too).

  14. #14
    Resident Java Hater
    Join Date
    Jul 2004
    Location
    Gerodieville Central, UK
    Posts
    446
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by dbevfat
    I think this is not a good example of using exceptions. The file closing code should be out of the try-catch block, since it has to be executed in any case (if the file is open) and it doesn't throw an exception. I'd also put the fopen() part outside the try-catch block. That way, I'd be sure that the file gets opened and closed, no matter what happens in the "risky" part of the code.
    I wasn't really illustrating a reallife scenario there. I was more illustrating that exceptions can make resources leak or run into problems if you are not careful with the design. Much like a C++ or OO book uses stupid shape classes such as triangle, circle etc and have shape as an abstract base class. I'm just trying to illustrate a possible issue with exceptions, I'm not provided "useful" cookbook code, much like the Shape classes are pretty useless in reallity

  15. #15
    SitePoint Guru dbevfat's Avatar
    Join Date
    Dec 2004
    Location
    ljubljana, slovenia
    Posts
    684
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I see, but since you gave an example in favor of error handling, rather then exceptions, I think you should've at least presented a problem that really shows a weakness of exceptions, not a programers' mistake. It's not exceptions that "make resources leak", it's their misuse.

    And those triangles, circles etc. are far from stupid - it's a very nice way to present abstract classes, since people are familiar with the idea. I guess it comes from young age of school time, when we learned about shapes, and later mathematics .


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •