awesomite/error-dumper

Pretty preview of errors and exceptions

v0.13.6 2017-12-22 00:07 UTC

README

Latest Stable Version Latest Unstable Version Codacy Badge Coverage Status Build Status

Debugger integrated with PhpStorm. ErrorDumper allows you to catch all kinds of errors and exceptions in PHP. You will be able to serialize, restore and display them later in readable form. @See example.

Table of contents

Installation

composer require awesomite/error-dumper

How to use?

Development environment

<?php

use Awesomite\ErrorDumper\ErrorDumper;

$errorDumper = new ErrorDumper();
$errorDumper->createDevHandler()
    ->registerOnError() // errors @see http://php.net/manual/en/function.trigger-error.php
    ->registerOnException() // uncaught exceptions
    ->registerOnShutdown(); // @see http://php.net/manual/en/function.error-get-last.php

// or

$errorDumper->createDevHandler()->register();

Production environment

Register handlers

<?php

use Awesomite\ErrorDumper\Handlers\ErrorHandler;
use Awesomite\ErrorDumper\Cloners\ClonedException;
use Awesomite\ErrorDumper\Listeners\ListenerClosure;

$callback = function ($exception) {
    /** @var \Exception|\Throwable $exception */
    $clone = new ClonedException($exception);
    $serialized = serialize($clone);
    // TODO store serialized exception
    // use $clone->getStackTrace()->getId() to count number of occurrences similar errors
    echo '503';
    exit(1);
};

$handler = new ErrorHandler();
$handler
    ->pushListener(new ListenerClosure($callback))
    ->register();

Display error in errorlog

<?php

use Awesomite\ErrorDumper\Views\ViewHtml;

$view = new ViewHtml();
// TODO fetch $serialized data from your storage
/** @var string $serialized */
$unserialized = unserialize($serialized);
$view->display($unserialized);

Sandbox

Popular case of sandbox usage

<?php

$sandbox->executeSafely(function () {
    /** @var \Twig_Environment $twig */
    $twig->render('template.twig');
});

Full story

PHP supports one error control operator: the at sign @ (@see). Try execute (without custom error handler) the following samples of code:

<?php

trigger_error('Test error');
echo 'OK';

Expected output:

Notice: Test error
OK
<?php

@trigger_error('Test error');
echo 'OK';

Expected output:

OK

Official PHP documentation says:

If you have set a custom error handler function with set_error_handler() then it will still get called, but this custom error handler can (and should) call error_reporting() which will return 0 when the call that triggered the error was preceded by an @.

It means there are two ways depend on your error_reporting settings:

error_reporting(E_ALL | E_STRICT)
<?php

error_reporting(E_ALL | E_STRICT);

set_error_handler(function ($code, $message, $file, $line) {
    if ($code & error_reporting()) {
        echo 'ERROR: ' . $message;
        exit;
    }
});

@trigger_error('Test'); // will do nothing
error_reporting(0)
<?php

error_reporting(0);

set_error_handler(function ($code, $message, $file, $line) {
    echo 'ERROR: ' . $message;
    exit;
});

@trigger_error('Test'); // will display "ERROR: Test" and will stop script

If you have error_reporting(0) you can need sandbox for errors:

<?php

use Awesomite\ErrorDumper\ErrorDumper;
use Awesomite\ErrorDumper\Handlers\ErrorHandler;

$errorDumper = new ErrorDumper();
$errorHandler = $errorDumper->createDevHandler(null, ErrorHandler::POLICY_ALL);
$errorHandler->register();

$sandbox = $errorHandler->getErrorSandbox();
$sandbox->executeSafely(function () {
    trigger_error('test'); // will do nothing
});

Instead of executeSafely you can use execute, which will throw exception in case of error.

<?php

use Awesomite\ErrorDumper\ErrorDumper;
use Awesomite\ErrorDumper\Sandboxes\SandboxException;

$errorDumper = new ErrorDumper();
$errorHandler = $errorDumper->createDevHandler();
$errorHandler->register();

try {
    $sandbox = $errorHandler->getErrorSandbox();
    $sandbox->execute(function () {
        trigger_error('test'); // will throw SandboxException
    });
} catch (SandboxException $exception) {
    header('Content-Type: text/plain');
    echo 'Error message: ' . $exception->getMessage() . "\n";
    echo 'Severity: ' . $exception->getSeverity() . "\n";
    echo 'Location in code: ' . $exception->getFile() . ':' . $exception->getLine();
    exit;
}

Integration with PhpStorm

<?php

use Awesomite\ErrorDumper\Views\ViewHtml;
use Awesomite\ErrorDumper\Editors\Phpstorm;
use Awesomite\ErrorDumper\Cloners\ClonedException;

$view = new ViewHtml();
$phpstorm = new Phpstorm();
$view->setEditor($phpstorm);

/** @var \Exception|\Throwable $exception */
$view->display(new ClonedException($exception));

ViewHtml has method setEditor. It allows you to achieve the following effect:

Links in stack trace

Click on line number and you will be redirected to PhpStorm directly from browser.

Skipping chosen exceptions

<?php

use Awesomite\ErrorDumper\Handlers\ErrorHandler;
use Awesomite\ErrorDumper\Listeners\ValidatorClosure;

$handler = new ErrorHandler();
$validator = new ValidatorClosure(function ($exception) {
    if ($exception instanceof \RuntimeException) {
        ValidatorClosure::stopPropagation();
    }
});
$handler->pushValidator($validator);

Versioning

The version numbers follow the Semantic Versioning 2.0.0 scheme.

Examples

To run examples you need at least PHP 5.4.

composer update --dev
bin/webserver.sh

Execute above commands and open in your browser url http://localhost:8001. To run example in terminal, execute bin/test.php.

Content Security Policy

This library uses *.js files hosted on maxcdn.bootstrapcdn.com and code.jquery.com (@see \Awesomite\ErrorDumper\Views\ViewHtml::getResources). Add those domains to your Content-Security-Policy header during display errors.

Symfony integration

Error Dumper Bundle.