HiveBrain v1.2.0
Get Started
← Back to all entries
debugphpMinor

Catching all exceptions and errors in PHP

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
exceptionsallphpcatchinganderrors

Problem

I've tried to catch all exceptions and errors in PHP in a way so that I can deal with them consistently.

This is the code with the exception of the very last bit where I instead pass $e on to a method that outputs an error page as HTML.

// Only let PHP report errors in dev
error_reporting(ENV === 'dev' ? E_ALL : 0);

// Register handler
set_error_handler("error_handler");
set_exception_handler("error_handler");
register_shutdown_function("error_handler");

function error_handler()
{
    // Check for unhandled errors (fatal shutdown)
    $e = error_get_last();

    // If none, check function args (error handler)
    if($e === null)
        $e = func_get_args();

    // Return if no error
    if(empty($e))
        return;

    // "Normalize" exceptions (exception handler)
    if($e[0] instanceof Exception)
    {
        call_user_func_array(__FUNCTION__, array(
            $e[0]->getCode(),
            $e[0]->getMessage(),
            $e[0]->getFile(),
            $e[0]->getLine(),
            $e[0]));
        return;
    }

    // Create with consistent array keys
    $e = array_combine(array('number', 'message', 'file', 'line', 'context'), 
                       array_pad($e, 5, null));

    // Output error page
    var_dump($e);
    exit;
}


I'm wondering if this is a decent way of doing it or if I have missed anything crucial. Any comments?

Solution

-
I don't think that printing raw errors/data to the users is a good idea:

var_dump($e);


They (usually) can't fix it, so it doesn't help them. (See #3 here) It might also contain sensitive information which could help attackers.

Instead of that you should log the errors to a log file, hide the details from the user (don't forget to print a friendly error message) and fix the errors. Your users might not call/mail you when they found a bug. They just simply use one of your competitor's service.

-
Instead of using the same function for three more or less different purposes:

set_error_handler("error_handler");
set_exception_handler("error_handler");
register_shutdown_function("error_handler");


I'd use three different functions (with proper signatures) which might call a fourth one. It would be cleaner (easier to read, understand and maintain). It would make unnecessary the internal magic with error_get_last(), func_get_args() and instanceof.

-

// Only let PHP report errors in dev
error_reporting(ENV === 'dev' ? E_ALL : 0);


It seems to me as a code smell: Test Logic in Production. I'd use php.ini to set this, I guess php.ini is a straightforward place for most of the PHP developers to set this instead of a PHP file.

Code Snippets

var_dump($e);
set_error_handler("error_handler");
set_exception_handler("error_handler");
register_shutdown_function("error_handler");
// Only let PHP report errors in dev
error_reporting(ENV === 'dev' ? E_ALL : 0);

Context

StackExchange Code Review Q#26957, answer score: 2

Revisions (0)

No revisions yet.