SitePoint Sponsor

User Tag List

Results 1 to 25 of 25
  1. #1
    SitePoint Enthusiast
    Join Date
    Jun 2007
    Location
    Manchester, UK
    Posts
    83
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Inteesting transcript about phps 'Exception Handling'

    Hi All,

    Heres an interesting conversation about PHP's 'Organisational' try/catch features.

    http://bugs.php.net/bug.php?id=40014

  2. #2
    SitePoint Enthusiast
    Join Date
    Nov 2006
    Posts
    50
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Basically, the author (expressing himself in a rather round-about way) thinks that a call to an undefined object method or undefined function should not be a fatal error.

    You can't do anything about the fatal error on a call to an undefined function (coding error anyway, surely?), but if you are worried about calls to an undefined object method during, say, careless polymorphism you could handle this gracefully in PHP5.

    PHP Code:
    class MySafeClass
    {
        function 
    __call($method,$arg)
        {
            throw new 
    BadFunctionCallException();
        }
    }

    try {
        
    $obj = new MySafeClass();
        
    $obj->mistake();
    } catch (
    BadFunctionCallException $e) {
        echo 
    'handled';

    Personally, I think if you are worried about encountering this sort of error in a production application, you have a big problem.

  3. #3
    SitePoint Wizard
    Join Date
    Feb 2007
    Posts
    1,274
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by robt View Post
    Basically, the author (expressing himself in a rather round-about way) thinks that a call to an undefined object method or undefined function should not be a fatal error.
    No, he is requesting that fatal errors also be catchable. Right now you have no means of getting control back to your own code; PHP will invoke the error handler. The rrorhandler is a rather coarse grained way to handle errors compared to exception handling blocks.

    He also points out the fact that every other language which has exception handling is able to catch such errors.

    In my experience, more than 9 out of 10 times you use exception handling, it is not to rectify the problem (which is often not possible) but to get control back at a place where from where the execution can safely continue and perhaps try again or use an alternative.

    Quote Originally Posted by robt View Post
    Personally, I think if you are worried about encountering this sort of error in a production application, you have a big problem.
    Sure, blame the programmer. Shame on him for pointing out that PHPs exception handling is incomplete, although documented as such.

    I can think of a number of scenarios where you'd want to get control back. Consider locks on critical objects, taking part in a communication where the protocol requires you to exit gracefully, finishing up on transactions etc. The requested enhancement would make meeting such requirements a lot easier.

  4. #4
    SitePoint Enthusiast
    Join Date
    Jun 2007
    Location
    Manchester, UK
    Posts
    83
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    PHP Try/Catch

    Hi,

    Honeymonster has hit the nail on the head, this is what I was getting at.

    Heres my scenario.

    Ok, I instantiate classes based on a class name passed in, this is from a get request (dont panic). Before the class is instantiated the page name is checked against a white list of allowable class names, and also for a-zA-Z only. I then proceed to instantiate the class if nothing has gone wrong. I know this may be overly paraniod because I know for sure that the class name will be valid if it is in the whitelist.

    So I wish to throw an exception if the class instantion fails so I can log and display a generic page maybe. But I cant cos I cant catch a fatal error, (well there are ways as the transcript states, but advised against).

    So I am having to use an if statement inside the try/catch block, to explicitly throw an exception. I know this maybe ok cos I can extend the exception class and create my own with logging features.

    thanks

  5. #5
    SitePoint Enthusiast
    Join Date
    Nov 2006
    Posts
    50
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by honeymonster View Post
    No, he is requesting that fatal errors also be catchable. Right now you have no means of getting control back to your own code; PHP will invoke the error handler.
    This was, roughly, supposed to be my point. A call to a non-existing function/method produces an E_ERROR, which is not caught by any user-defined error/exception handler. So he's requesting that these errors aren't "fatal" in the true sense of the word. Maybe I'm confusing my terminology, I haven't had the fortune to code in Java/etc. You can get round this explicitally yourself for objects, but not for function calls.

    Quote Originally Posted by honeymonster View Post
    I can think of a number of scenarios where you'd want to get control back. Consider locks on critical objects, taking part in a communication where the protocol requires you to exit gracefully, finishing up on transactions etc. The requested enhancement would make meeting such requirements a lot easier.
    I understand the need to recover from an error, but my piont was I don't quite see how a call an undefined function might be the result of something beyond the coders control. Or is this me being naive, any concrete examples?

  6. #6
    SitePoint Enthusiast
    Join Date
    Nov 2006
    Posts
    50
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by bustacapinya View Post
    So I wish to throw an exception if the class instantion fails so I can log and display a generic page maybe. But I cant cos I cant catch a fatal error, (well there are ways as the transcript states, but advised against).

    So I am having to use an if statement inside the try/catch block, to explicitly throw an exception. I know this maybe ok cos I can extend the exception class and create my own with logging features.
    Oops, didn't see this before my reply. In this situation, you know the class exists, right? So when you instantiate the class, an error might occur in the constructor? What's wrong with throwing an exception in the constructor if it fails? I don't really get the need for a change in the core PHP code here.

    I too would like normal errors to be caught like exceptions, but is this not a separate issue to the "fatal" status of undefined method calls?

    "Handleable PHP normal errors should be caught by a catch block". Yup, great idea.

    "Undefined method/function calls should be handleable." Me, I'm not fussed.

  7. #7
    SitePoint Enthusiast
    Join Date
    Jun 2007
    Location
    Manchester, UK
    Posts
    83
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    PHP Try/Catch

    Hi Robt

    incase your interested, heres the code Im using $pages is a white list of page names, I fear I may be being overly paranoid?

    PHP Code:
    $name trim($_GET['n']);
    MancProf::initMP($da);
    try {
      if(!isset(
    $pages[$name]) || !ctype_alpha($name)) {
          throw new 
    MancProfException('Unknown Page Name');
      }else {
          
    requireFiles($name$pages[$name]);
          
    $className $name 'Controller';
          
    $obj = new $className($da);
          
    defaultActions();
      }
    } catch(
    MancProfException $e) {
        
    requireFiles('SiteHome');
        
    $obj = new SiteHomeController($da);
        
    defaultActions();


  8. #8
    SitePoint Enthusiast
    Join Date
    Nov 2006
    Posts
    50
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    What do you want it to be, if the feature in question was implemented?

  9. #9
    SitePoint Enthusiast
    Join Date
    Jun 2007
    Location
    Manchester, UK
    Posts
    83
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    the thing is, if somthing goes wrong on the line:

    PHP Code:
    $obj = new $className($da); 
    I cannot recover from the error, I can only make sure the classname is valid before i attempt to instantiate. Theres little chance of me getting an error here cos I checked against a whitelist, (maybe overkill).

    In other try/catch implementations such as Java, I could simply try to instantate the class then catch the error on failure, (Im talking about trying to instantiate an undefined class) without the need even for an if statement!

    thats all, so I cant see try/catch being much use at its current PHP implementation apart from an code orgainsational point of view maybe,

  10. #10
    SitePoint Enthusiast
    Join Date
    Nov 2006
    Posts
    50
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by bustacapinya View Post
    In other try/catch implementations such as Java, I could simply try to instantate the class then catch the error on failure, (Im talking about trying to instantiate an undefined class) without the need even for an if statement!
    In PHP5,

    (edit: bustacapinya points out later in the thread that this code results in a fatal error. Oops.)

    PHP Code:
    function __autoload($name)
    {
        throw new 
    Exception("class $name doesn't exist");

    In your specific example, if you didn't check that $name is a value in your whitelist (I don't think the ctype_alpha check really adds much, given you're already using a whitelist), then you are feeding a user supplied parameter staright into your requireFiles function before any instantiation. This sounds a little dangerous to me, depending on what requireFiles does.

    Quote Originally Posted by bustacapinya View Post
    I cannot recover from the error, I can only make sure the classname is valid before i attempt to instantiate. Theres little chance of me getting an error here cos I checked against a whitelist, (maybe overkill).
    If a class on your whitelist doesn't exist, you have made a mistake in your whitelist. In this case, the programmer is to blame, and the error should be caught (and corrected) well before publishing a production version.
    Last edited by robt; Aug 5, 2007 at 06:07. Reason: talking rubbish.

  11. #11
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by robt View Post
    So he's requesting that these errors aren't "fatal" in the true sense of the word. Maybe I'm confusing my terminology, I haven't had the fortune to code in Java/etc. You can get round this explicitally yourself for objects, but not for function calls.
    In Java, there is no notion of errors. There are only exceptions. So even very bad errors are handled with exceptions. Of course that particular case is impossible in Java.

    I think the problem is, that PHP has a hybrid system. Exceptions are more powerful than the old error-handler, but they are weakened by the fact, that they only work to some point, after which the error handler takes over.

    Quote Originally Posted by robt View Post
    "Handleable PHP normal errors should be caught by a catch block". Yup, great idea.
    You probably know, but this is already quite possible, by throwing an error from a custom exception handler.

  12. #12
    SitePoint Enthusiast
    Join Date
    Jun 2007
    Location
    Manchester, UK
    Posts
    83
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    PHP Try/Catch


    posted by robt:

    In your specific example, if you didn't check that $name is a value in your whitelist (I don't think the ctype_alpha check really adds much, given you're already using a whitelist), then you are feeding a user supplied parameter staright into your requireFiles function before any instantiation. This sounds a little dangerous to me, depending on what requireFiles does.
    I'm aware of that, thats where the whitelist comes in, the above is like saying if I didnt use Prepared statements I'd be exposed to injection attacks.


    posted by robt:

    If a class on your whitelist doesn't exist, you have made a mistake in your whitelist. In this case, the programmer is to blame, and the error should be caught (and corrected) well before publishing a production version
    I understand wat your sayng here so i guess im just being far too over cautious


    Thanks for your thoughts

  13. #13
    SitePoint Enthusiast
    Join Date
    Nov 2006
    Posts
    50
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by bustacapinya View Post
    I'm aware of that, thats where the whitelist comes in, the above is like saying if I didnt use Prepared statements I'd be exposed to injection attacks.
    Sorry, I don't mean to patronise! Long day at the office, on a saturday too.

    Quote Originally Posted by kyberfabrikken View Post
    You probably know, but this is already quite possible, by throwing an error from a custom exception handler.
    I presume you mean the other way round (?), but this didn't occur to me. Learn something new everyday, thanks.

  14. #14
    SitePoint Enthusiast
    Join Date
    Jun 2007
    Location
    Manchester, UK
    Posts
    83
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    PHP Try/Catch

    No Worries,

    Sorry for being sarcastic , thanks for your thoughts anyhow its been interesting

  15. #15
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by robt View Post
    I presume you mean the other way round (?), but this didn't occur to me. Learn something new everyday, thanks.
    You're right - The other way round of course. I use that all the time. SPL supplies an ErrorException class, which can be used for this purpose.

  16. #16
    SitePoint Evangelist
    Join Date
    Jun 2003
    Location
    Melbourne, Australia
    Posts
    440
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kyberfabrikken View Post
    SPL supplies an ErrorException class
    Er... where might that be?
    Zealotry is contingent upon 100 posts and addiction 200?

  17. #17
    SitePoint Wizard
    Join Date
    Feb 2007
    Posts
    1,274
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by robt View Post
    If a class on your whitelist doesn't exist, you have made a mistake in your whitelist. In this case, the programmer is to blame, and the error should be caught (and corrected) well before publishing a production version.
    Sorry, but I really have to take issue with this statement. In my opinion it is a somewhat immature approach to code quality, and one which have landed more companies than Microsoft in hot water.

    You should not code assuming that yoyr code will not fail. You can test 'till the cows come home, you will not be able to find all of the errors in your scripts/programs by testing. And then consider the situations where you rely on other peoples perfections (or imperfections). Frameworks has bugs, extensions has bugs. A future change to your code may introduce a bug.

    You are homing in on bustacapinyas example where the gives an example of how me may make a mistake. Of course he shouldn't make mistakes such as that. We can all say "well, then blame the programmer, that a programming error". On top of that you only need to extend his example somewhat and put the class names in a configuration file (for pluggability). Then it suddently is not a programming error but a configuration error. Now we blame the admin?

    Bustacapinya is being realistic. We need protection against errors in depth. We need to realize that bug and errors happen, and *will* happen in production. What we need to do is to limit their effect, e.g. not leave database connections open, not leave communication partners left halfway through a protocol, not leave manual "locks" in an invalid state, not leave files half-written etc. etc.

    Structured exception handling (as opposed to just error handlers) allow programmers to "clean up" on the way out, so to speak. It also allows them to possibly try an alternative which could rectify the problem. If such an alternative exists we would like the code to continue as normal afterwards. In a number of situations in PHP this is not possible.

    The equivalent to bustacapinyas example in Java would be Class.forName(). It's a method which creates a class based on a name in a string parameter. Guess what, if the class doesn't exist - it will throw an exception, which can be caught.

  18. #18
    SitePoint Wizard
    Join Date
    Feb 2007
    Posts
    1,274
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kyberfabrikken View Post
    I think the problem is, that PHP has a hybrid system. Exceptions are more powerful than the old error-handler, but they are weakened by the fact, that they only work to some point, after which the error handler takes over.
    I believe that you are right. PHP being glue cannot "catch" any error generated by its extensions. An extension can conceivably overwrite critical memory and leave the entire PHP instance in an unknown state. Hence, fatal errors are needed.

    But a number of un-catchable errors are generated by PHP itself; although they can be demonstrated to not ruin the environment. Why shouldn't they be catchable?

  19. #19
    SitePoint Enthusiast
    Join Date
    Nov 2006
    Posts
    50
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by honeymonster View Post
    You should not code assuming that yoyr code will not fail. You can test 'till the cows come home, you will not be able to find all of the errors in your scripts/programs by testing. And then consider the situations where you rely on other peoples perfections (or imperfections). Frameworks has bugs, extensions has bugs. A future change to your code may introduce a bug.
    Of course I agree with this. I am not arrogant enough to believe that my code has any less bugs than anyone else's. I have also not disagreed with the point that it would be better if all "fatal" errors are catcheable. Clearly, it's a no brainer.

    I have tried to point out that there are explicit ways that this problem can be dealt with in terms of instantiating undeclared classes (__autoload), and undefined object calls (__call).

    I have stated that I'm not particularly fussed by this fatality, perhaps because I have not coded with a truly OOP language. I am a mathematical modeller in the day-job, so perhaps I am immature as a web developer in this respect. I am happy to accept that sometimes things go truly horribly wrong. It can never get too bad because the PHP environment is not persistent between requests. I prefer this in some ways - I can code based on the assumption that the whole server may die in the middle of anything, so need to use transactions etc. I do my best to catch and deal with errors that I can, but am happy enough that some are will never be caught. I know I can't always rely on my error handling process working, and prefer it this way. Even Java will not catch an exception if the server goes tits up.

    Quote Originally Posted by honeymonster View Post
    Sorry, but I really have to take issue with this statement. In my opinion it is a somewhat immature approach to code quality, and one which have landed more companies than Microsoft in hot water.

    ....

    You are homing in on bustacapinyas example where the gives an example of how me may make a mistake.
    And you are generalising my comment on bustacapinyas example beyond its scope. In his case, with a hard coded whitelist it would be a crass mistake. In other cases it may be quite likely, and in those cases some error handling may be prudent.
    Last edited by robt; Aug 5, 2007 at 06:11. Reason: speeling

  20. #20
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by auricle View Post
    Er... where might that be?
    Yeah ... apparently it's simply part of PHP5 - not SPL.

    http://www.php.net/exceptions#65203

  21. #21
    SitePoint Enthusiast
    Join Date
    Jun 2007
    Location
    Manchester, UK
    Posts
    83
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    PHP Try/catch

    I have tried to point out that there are explicit ways that this problem can be dealt with in terms of instantiating undeclared classes (__autoload), and undefined object calls (__call).
    What about if you dont have the file for __autoload to use? (fatel error) this is what Im getting at, of course ive done everything I can to make sure the class name is valid, but you can be never be that sure in my opinion.

    As far as I understand __autoload is only usefull when you have the required file already, just that is hasnt been 'required' yet. Im talking about situations where I dont even have the file/class. I know I have a hardcoded whitelist but I think gaurding against this in my opinion is hardly crass.
    Last edited by bustacapinya; Aug 5, 2007 at 05:37. Reason: typos

  22. #22
    SitePoint Enthusiast
    Join Date
    Nov 2006
    Posts
    50
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by php_manual
    Note: Exceptions thrown in __autoload function cannot be caught in the catch block and results in a fatal error.
    Ok, I didn't realise this. I take it back, you can't do anything about it! Not doing too well so far, am I ? I'll need a ladder soon to get out the hole I'm digging for myself. In your case could you not use class_exists to check in your requireFiles function?

  23. #23
    SitePoint Wizard
    Join Date
    Feb 2007
    Posts
    1,274
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by robt View Post
    Ok, I didn't realise this. I take it back, you can't do anything about it! Not doing too well so far, am I ? I'll need a ladder soon to get out the hole I'm digging for myself. In your case could you not use class_exists to check in your requireFiles function?
    No need for a ladder when you've got a sense of humor.

    I suspect that you are right, that there's probably ways around it. What the original request was suggesting was one consistent way of handling errors, programming errors or otherwise. Like that of other programming languages.

    It may not be as serious in a web setting as it would be in a service or a desktop application. But consider such errors arises in an add rotator module. Would you like to have the entire page fail, or just the add part go blank?

  24. #24
    SitePoint Enthusiast
    Join Date
    Jun 2007
    Location
    Manchester, UK
    Posts
    83
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    PHP Try/Catch

    No need for a ladder when you've got a sense of humor.
    toshay!


    In your case could you not use class_exists to check in your requireFiles function?
    yes thanks, I could invoke this as a final check.

  25. #25
    SitePoint Enthusiast
    Join Date
    Jun 2007
    Location
    Manchester, UK
    Posts
    83
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Also,
    PHP Code:
    require_once() 
    always throws a fatal error, so its impossible to do any processing after a require_once statement, you have to use
    PHP Code:
     include_once() 
    I've read the above is much faster also?


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
  •