Skip to content
/ error Public
forked from kuria/error

Makes handling and debugging PHP errors suck less.

License

Notifications You must be signed in to change notification settings

vinala/error

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Error handler

Makes handling and debugging PHP errors suck less.

Table of Contents

Features

  • debug and non-debug mode
  • converts PHP errors (warnings, notices, etc) into exceptions
    • respects the global error_reporting setting
  • handles uncaught exceptions and fatal errors (including parse errors)
  • CLI error screen (writes errors to STDERR)
  • web error screen (renders errors for web browsers)
    • non-debug mode:
      Web error screen in non-debug mode
      • simple error message
      • does not disclose any internal information
      • does not use any variation of the word "oops"
    • debug mode:
      Web error screen in debug mode
      • file paths and line numbers
      • highlighted code previews
      • stack traces
      • argument lists
      • variable contexts
      • output buffer (can be shown as HTML too)
      • plaintext trace (for copy-paste)
  • event system that can be utilised to:
    • implement logging
    • suppress or force errors conditionally
    • change or add content to the error screens

Requirements

  • PHP 5.3 or newer

Usage example

use Vinala\Error\ErrorHandler;

$debug = true; // true during development, false in production
error_reporting(E_ALL | E_STRICT); // configure the error reporting

$errorHandler = new ErrorHandler($debug);
$errorHandler->register();

// trigger an error to see the error handler in action
echo $invalidVariable;

Event system

  • implemented using the kuria/event library
  • the error handler fires events as it handles errors
  • both built-in error screen implementations emit events as they render

Error handler events

Possible events emitted by the ErrorHandler class:

error

  • emitted when a PHP errors occurs
  • arguments:
    1. object $exception
      • instance of ErrorException or Vinala\Error\ContextualErrorException
    2. bool $debug
    3. bool &$suppressed
      • reference to the suppressed state of the error
      • the error can be suppressed by current error_reporting configuration or by other event handlers

fatal

  • emitted when an uncaught exception or a fatal error is being handled
  • arguments:
    1. object $exception
    2. bool $debug
    3. FatalErrorHandlerInterface &$handler
      • reference to the current fatal error handler

emerg

  • emitted when another exceptions has been thrown during fatal error handling
  • more uncaught exceptions or a fatal error at this point will just kill the script
  • arguments:
    1. object $exception
    2. bool $debug

Web error screen events

Possible events emitted by the WebErrorScreen class:

render

  • emitted when rendering in non-debug mode
  • single argument - an event array with the following keys:
    • &title: used in <title>
    • &heading: used in <h1>
    • &text: content of the default paragraph
    • &extras: custom HTML after the main section
    • exception: the exception
    • output_buffer: string|null
    • screen: instance of WebErrorScreen

render.debug

  • emitted when rendering in debug mode
  • single argument - an event array with the following keys:
    • &title: used in <title>
    • &extras: custom HTML after the main section
    • exception: the exception
    • output_buffer: string|null
    • screen: instance of WebErrorScreen

layout.css

  • emitted when CSS styles are being output
  • single argument - an event array with the following keys:
    • &css: the CSS output
    • debug: boolean
    • screen: instance of WebErrorScreen

layout.js

  • emitted when JavaScript code is being output
  • single argument - an event array with the following keys:
    • &js: the JS output
    • debug: boolean
    • screen: instance of WebErrorScreen

CLI error screen events

Possible events emitted by the CliErrorScreen class:

render

  • emitted when rendering in non-debug mode
  • single argument - an event array with the following keys:
    • &title: first line of output
    • &output: error message
    • exception: the exception
    • output_buffer: string|null
    • screen: instance of WebErrorScreen

render.debug

  • emitted when rendering in debug mode
  • single argument - an event array with the following keys:
    • &title: first line of output
    • &output: error message
    • exception: the exception
    • output_buffer: string|null
    • screen: instance of WebErrorScreen

Event listener examples

Notes

  • do not typehint the Exception class in your listeners if you want to be compatible with the new exception hierarchy in PHP 7

Logging

Logging unhandled errors into a file.

use Vinala\Error\Util\Debug;

$errorHandler->on('fatal', function ($exception, $debug) {
    $logFilePath = sprintf('./errors_%s.log', $debug ? 'debug' : 'prod');

    $entry = sprintf(
        "[%s] %s - %s in file %s on line %d\n",
        date('Y-m-d H:i:s'),
        Debug::getExceptionName($exception),
        $exception->getMessage(),
        $exception->getFile(),
        $exception->getLine()
    );

    file_put_contents($logFilePath, $entry, FILE_APPEND | LOCK_EX);
});

Disabling the "@" operator

This listener causes statements like echo @$invalidVariable; to throw an exception regardless of the "shut-up" operator.

$errorHandler->on('error', function ($exception, $debug, &$suppressed) {
    $suppressed = false;
});

Altering the error screens

Examples for the web error screen.

Changing default labels of the non-debug error screen:

use Vinala\Error\Screen\WebErrorScreen;

$errorHandler->on('fatal', function ($exception, $debug, $screen) {
   if (!$debug && $screen instanceof WebErrorScreen) {
        $screen->on('render', function ($event) {
            $event['heading'] = 'It is all your fault!';
            $event['text'] = 'You have broken everything and now I hate you.';
        });
    }
});

Adding customized section to the debug screen:

use Vinala\Error\Screen\WebErrorScreen;

$errorHandler->on('fatal', function ($exception, $debug, $screen) {
   if ($debug && $screen instanceof WebErrorScreen) {
        $screen
            ->on('layout.css', function ($event) {
                $event['css'] .= '#custom-group {color: #f60000;}';
            })
            ->on('render.debug', function ($event) {
                $event['extras'] .= <<<HTML
<div id="custom-group" class="group">
    <div class="section">
        Example of a custom section
    </div>
</div>
HTML;
            })
        ;
    }
});

About

Makes handling and debugging PHP errors suck less.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • PHP 100.0%