0

EDIT: about the linked answer above, it's similar but different, since my goal is to debug the error in the error page.


Sometimes an unexpected error is hard to debug, since the error report is printed inside strange HTML elements, like an hidden div or a option element.

Is there not a way to automatically store error objects in a global variable and redirect the script to an error page, if any uncaught error is fired? And is there a way to do this for all errors, included the ones that normally doesn't quit the script, like warnings and notices?

4
  • possible duplicate of catching all errors and redirecting to page with php Commented Jun 13, 2013 at 8:23
  • 1
    Did you try reading about PHP Exceptions php.net/manual/en/language.exceptions.php ? Commented Jun 13, 2013 at 8:24
  • @JamesDonnelly: well, it's not a duplicate, since I want to do it for any error. Commented Jun 13, 2013 at 9:34
  • @MladenB.: so essentially I have to convert error to exceptions using this example: php.net/manual/en/… and make my own exception handler, right? Where can I find the code of the default exception handler? Commented Jun 13, 2013 at 9:48

3 Answers 3

4

You do this with a custom error handler. Turning errors into exceptions is a good way and allows you very fine grained control over error handling:

set_error_handler(function ($errno, $errstr, $errfile, $errline) {
    throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
});

You may decide for which errors to throw exceptions and which to ignore; for example you may want to ignore or just log E_NOTICEs. With a global try..catch block or a custom exception handler you can now very easily decide what to do in case of errors.

Sign up to request clarification or add additional context in comments.

3 Comments

... Also you should know about the ob_* set of functions: php.net/manual/en/ref.outcontrol.php . Buffer your site output and flush it only when no errors were happening, if an error occurs just show the error page and throw away the original site output
@hek2mgl: I do not know if I can encapsulate what you suggest me. I want to easily turn this off when the site will go in production.
I solved it without completely rewriting the error handler, see my answer :)
1

Indeed there are ways to both redirect errors to pages, log them, track them, and what not. PHP is quite flexible. The good news is you don't have to homecook such methods, frameworks are available for that, but you can also survive without these as built in error handling facilities of PHP are sufficiently usable. If configured properly, PHP will abort on errors (or warnings, you decide), log them, and even return HTTP 500 Server Error code if plugged into a web server.

You may need to configure PHP properly. It is perfectly capable of a better error handling workflow. First of all, disable error printing, this is not how well behaved applications should report errors, and at worst, helps malicious users to break their way into your systems, using printed error output. You are not the only one viewing your webpages, you know, and not all users get confused seeing these, some wait for these. This is one of the directives you can use, editing the "php.ini" file, which configures PHP; it disables mixing error output with whatever else PHP outputs as part of content generation:

display_errors = "0"

You can also set it to "stderr", which is a good thing to do when debugging scripts using command line PHP invocation, as the output will be sent to another file channel, the so called standard error.

Take now heed of the following "php.ini" directive:

log_errors = "1"

The above will have PHP log errors either to a file or using web servers error logging facilities, depending on how PHP is invoked. On UNiX systems, the log file, listing the error and its details, will reside in "/var/log/www/", for instance.

Take a good read through the PHP documentation on error handling and reporting, starting perhaps at the following page:

http://www.php.net/manual/en/book.errorfunc.php

Don't forget to read on installation configuration. And I repeat again, NEVER have PHP display errors for a public PHP script! (and yes, I am aware that you are debugging, but I can't stress this point enough these days).

2 Comments

I prefer to show the errors during development, since it's more fast to debug. I'll log errors when the site will go in production.
Why not, @Lucas. However, I find that displaying errors during development may interfere with debugging itself, as there is a possibility that error output may creep in in the kind of elements that are not visible. Also, warnings and other important information may end up in the log file you don't bother to look at until after you decide to release. Same goes for 500 Server Error codes - your scripts will generate output yet PHP may change the response error code, which may break your pages if these are served to for instance Adobe Flash Player clients or web service consumers.
0

Thanks to @MladenB. and deceze, I solved my problem. This is how I coded the solution:

in a config.php file, to be included in your scripts (it's better to move the functions to a personal library file):

<?php

function my_error_handler($errno, $errstr, $errfile, $errline)
{
    throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}

function my_exception_handler($e)
{
    /**
     *  Exception handler that pass the error object to an error page.
     *  This is to avoid bad displaying or hiding of error reports.
     *  
     *  @param $e Exception  The exception to manage
     */

    if (session_status() !== PHP_SESSION_ACTIVE)
    {
        session_start();
    }

    session_register_shutdown();

    $_SESSION['error'] = $e;

    header('Location: error.php');
    exit();
}

set_error_handler('my_error_handler');
set_exception_handler('my_exception_handler');

in error.php:

<?php

session_start();
session_register_shutdown();

$e = $_SESSION['error'];

echo '<h2>Stack trace</h2>';
echo var_dump($e->getTrace());

throw $e;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.