#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    5
    Rep Power
    0

    How do I display a meaningful error message in PHP in case of out-of-memory?


    My company is running an internal MediaWiki site on LAMP, which is actively used and has a number of custom modifications. Some users write really big DPL queries, and some of those queries actually exceed the configured memory limit per request.

    The problem is that when PHP runs out of memory, it simply returns an HTTP error 500 and a blank page. I am trying to install a custom error handler which would return something useful to the user, e.g. "your query is too big and exceeded the alotted memory limit". I looked up the docs and found how it (supposedly) can be done; the problem is that the solution simply doesn't work. here is what i am trying to do:

    PHP Code:
    register_shutdown_function ('shutdown_handler');

    function 
    shutdown_handler () {
        
    $err error_get_last();
        if (
    $err && $err['type'] && ($err['type'] > 0) && ($err['type'] < 10)) {
        
    error_reporting(-1);
        
    ini_set('display_errors'1);
        
    ini_set('display_startup_errors'1);
        
    $message sprintf ("*** Error %s: %s\n"$err['type'], $err['message']);
        
    error_log ($message);

        
    header('HTTP/1.1 200'true); 
        
        print (
    $message);

        
    error_log ("Buffer contents:\n\n" ob_get_contents());

        
    flush ();
        
    ob_end_flush();
        exit ();
        }

    Basically a lot of debug code in there. I trap the error, and i log all the pertinent into via the "error_log". I can set the response headers and HTTP code, and the browser receives it (in this case, i was setting it to 200 just because I felt like it). But no matter what I do, I cannot get any output to display to the user in their browser!

    That "print" statement should work. The output string is in the buffer, I can see it in the buffer dump, and I am flushing the buffer -- but the browser simply receives no HTML content, nothing. Blank page.

    Any ideas?
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Loyal (3000 - 3499 posts)

    Join Date
    Jul 2003
    Posts
    3,397
    Rep Power
    594
    I don't know if it will work on an out of memory error but I suggest you use a try/catch on your query.
    There are 10 kinds of people in the world. Those that understand binary and those that don't.
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    5
    Rep Power
    0
    it won't, because it's not my query -- I won't modify the core mediawiki code. Also, out-of-memory is a fatal error anyway, and thus not catchable. It must be handled via a special error handler, and it IS being thusly handled -- it's just that I can't seem to figure out how to let the user see a human-friendly error message!
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Loyal (3000 - 3499 posts)

    Join Date
    Jul 2003
    Posts
    3,397
    Rep Power
    594
    If it is a fatal PHP error then I see no way to catch it since, obviously, PHP stops executing. It is not PHP returning a 500 but httpd. There is no way to handle that with PHP.

    I can only suggest you modify httpd's 500 message to indicate there may have been an excessively large query.

    Comments on this post

    • badger_fruit agrees
    Last edited by gw1500se; November 5th, 2012 at 01:32 PM.
    There are 10 kinds of people in the world. Those that understand binary and those that don't.
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Dec 2004
    Posts
    2,972
    Rep Power
    375
    not sure if this will work, i am doing a large loop, just before i start that loop i note down the time. inside the loop i check if this time is >50, if it is i know the script is close to the time limit (60 sec) so i exit the loop.
  10. #6
  11. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    5
    Rep Power
    0
    Originally Posted by gw1500se
    If it is a fatal PHP error then I see no way to catch it since, obviously, PHP stops executing. It is not PHP returning a 500 but httpd. There is no way to handle that with PHP.
    Clearly there is, by installing the special handler, since I am in fact handling it, recording the error, and logging it to the Apache log_file. Those error_log commands in my code? They work and produce output.

    I got the error catching and handling figured. What I am missing is knowing how to send back a human-friendly error message.

    Comments on this post

    • gw1500se disagrees : There is something wrong with your explaination. There is no way to catch a fatal PHP error with PHP.
  12. #7
  13. Confused badger
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Mar 2009
    Location
    West Yorkshire
    Posts
    1,112
    Rep Power
    487
    Surely if you're getting an internal server error, then you can't use a script to handle this, instead, like gw1500se suggested, write a custom 500 page and have apache display that instead of the 'standard' one.
    "For if leisure and security were enjoyed by all alike, the great mass of human beings who are normally stupefied by poverty would become literate and would learn to think for themselves; and when once they had done this, they would sooner or later realise that the privileged minority had no function and they would sweep it away"
    - George Orwell, 1984
  14. #8
  15. No Profile Picture
    Lost in code
    Devshed Supreme Being (6500+ posts)

    Join Date
    Dec 2004
    Posts
    8,317
    Rep Power
    7170
    When I copy and paste your code onto my machine and add some code to burn memory below it I get the expected output from your script. So whatever is causing the output to not show up is somehow related to the environment in which you're running it, there is nothing wrong with the code itself.

    It might be something with your web server configuration, or it might be something that MediaWiki is doing. First, I would figure that out. Try putting just the following into a php file by itself:
    PHP Code:
    <?php
        
        register_shutdown_function
    ('shutdown_handler');

        function 
    shutdown_handler () {
            
    $err error_get_last();
            if (
    $err && $err['type'] && ($err['type'] > 0) && ($err['type'] < 10)) {
                
    error_reporting(-1);
                
    ini_set('display_errors'1);
                
    ini_set('display_startup_errors'1);
                
    $message sprintf ("*** Error %s: %s\n"$err['type'], $err['message']);
                
    //error_log ($message);

                
    header('HTTP/1.1 200'true); 
                
                print (
    $message);

                
    //error_log ("Buffer contents:\n\n" . ob_get_contents());

                
    flush ();
                
    ob_end_flush();
                exit ();
            }
        }
        
        
    ini_set('memory_limit''2M');
        
    ini_set('display_errors'0);
        for(
    $a ''1$a .= 'a');
    If you see the error message, then it's something related to MediaWiki. If not, then it's something related to your server environment.
    PHP FAQ

    Originally Posted by Spad
    Ah USB, the only rectangular connector where you have to make 3 attempts before you get it the right way around
  16. #9
  17. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    5
    Rep Power
    0
    Originally Posted by badger_fruit
    Surely if you're getting an internal server error, then you can't use a script to handle this.
    Why do people keep telling me that I cannot do something I am in fact actually doing?
  18. #10
  19. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    5
    Rep Power
    0
    Originally Posted by E-Oreo
    If you see the error message, then it's something related to MediaWiki. If not, then it's something related to your server environment.
    DOH, I should have thought of checking that out, thanks.
  20. #11
  21. No Profile Picture
    Contributing User
    Devshed Loyal (3000 - 3499 posts)

    Join Date
    Jul 2003
    Posts
    3,397
    Rep Power
    594
    OK, E-Oreo. Please explain how you can catch a fatal PHP error with PHP.
    There are 10 kinds of people in the world. Those that understand binary and those that don't.
  22. #12
  23. Confused badger
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Mar 2009
    Location
    West Yorkshire
    Posts
    1,112
    Rep Power
    487
    It's simple, you get this REALLY big net ....
    "For if leisure and security were enjoyed by all alike, the great mass of human beings who are normally stupefied by poverty would become literate and would learn to think for themselves; and when once they had done this, they would sooner or later realise that the privileged minority had no function and they would sweep it away"
    - George Orwell, 1984
  24. #13
  25. No Profile Picture
    Contributing User
    Devshed Loyal (3000 - 3499 posts)

    Join Date
    Jul 2003
    Posts
    3,397
    Rep Power
    594
    Or we are not really dealing with a fatal PHP error.
    There are 10 kinds of people in the world. Those that understand binary and those that don't.
  26. #14
  27. No Profile Picture
    Lost in code
    Devshed Supreme Being (6500+ posts)

    Join Date
    Dec 2004
    Posts
    8,317
    Rep Power
    7170
    A shutdown handler runs after the PHP script finishes execution. A PHP script might finish execution for a variety of reasons, including reaching the end or hitting a fatal error. The shutdown handler will still run regardless of the reason the script stopped executing in almost all cases. The only cases in which it wouldn't run would be an error that actually halts the PHP interpreter, like a segmentation fault.

    The shutdown handler is not really "catching" the error so much as it is just detecting it. The shutdown handler cannot tell PHP to ignore the error, since the script has already ended when it is run. Additionally, the shutdown handler runs regardless of whether or not an error occurs.

    The only caveat is that your PHP script has to register the shutdown handler before the fatal error. This means it would not be able to detect a syntax error occurring in the file where the shutdown handler is registered, but would be able to detect a syntax error in included files.

    This is possible because PHP is a scripting language and is executed by an interpreter. If PHP were a compiled language like C, then a fatal error would be completely fatal because the whole process would be killed outright. A fatal PHP error does not kill the interpreter though; the interpreter detects the fatal error and handles it (usually by displaying an error message and shutting down).

    The inability to catch fatal PHP errors in a normal PHP error handler is by design rather than for technical reasons.
    Last edited by E-Oreo; November 6th, 2012 at 05:32 PM.
    PHP FAQ

    Originally Posted by Spad
    Ah USB, the only rectangular connector where you have to make 3 attempts before you get it the right way around
  28. #15
  29. No Profile Picture
    Contributing User
    Devshed Loyal (3000 - 3499 posts)

    Join Date
    Jul 2003
    Posts
    3,397
    Rep Power
    594
    This is why I follow this forum. There is always something new to learn. I was not aware of a "shutdown handler." I'll have to read up on that. Thanks.

    Comments on this post

    • badger_fruit agrees : lol, same here! <3 to e-oreo!!
    There are 10 kinds of people in the world. Those that understand binary and those that don't.

IMN logo majestic logo threadwatch logo seochat tools logo