vinala / error
Makes handling and debugging PHP errors suck less.
Installs: 14
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 1
Forks: 1
pkg:composer/vinala/error
Requires
- php: >=5.3.0
- kuria/event: ~1.0.0
This package is not auto-updated.
Last update: 2025-10-20 19:39:07 UTC
README
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_reportingsetting
 
- respects the global 
- 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:
 - simple error message
- does not disclose any internal information
- does not use any variation of the word "oops"
 
- 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)
 
 
- non-debug mode:
- 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:
- object $exception- instance of ErrorExceptionorVinala\Error\ContextualErrorException
 
- instance of 
- bool $debug
- bool &$suppressed- reference to the suppressed state of the error
- the error can be suppressed by current error_reportingconfiguration or by other event handlers
 
 
fatal
- emitted when an uncaught exception or a fatal error is being handled
- arguments:
- object $exception
- bool $debug
- 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:
- object $exception
- 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 Exceptionclass 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;
            })
        ;
    }
});