Custom Error Handler in PHP
How to create a custom error handler for PHP that handles non-fetal errors.
By. Jacob
Edited: 2021-04-18 16:49
PHP allows the creation of a custom error handler to handle traditional error messages, also known as diagnostic errors; this can be a welcome help to developers while trying to debug certain types of non-fetal errors. If your system allows it, you can enable errors for admins while disabling them for visitors and non-admin users.
In order to make your own error handler, you need to use the set_error_handler function to define your custom function or method. A simple example function is included in this tutorial to show you how it is done.
The example function will handle all errors that can be handled by a custom error handler, but you may want to get rid of the echo statements, and instead include a proper HTML template.
In OOP, you would do like this to define your custom error handler function:
$error_handler = new my_error_handler();
set_error_handler(array($error_handler, 'my_error_handler_method'));
If you are just using a custom function, you would instead do like this:
set_error_handler('my_error_handler_function');
Please read the following sections for more details on the implementation.
A simple custom error handler
The following is just a simple function to demonstrate how you can catch errors, it can be improved further by adding support for loading HTML templates and translating error messages.
1. First, write your error function:
error_handler($errno, $errstr, $errfile, $errline) {
if (!(error_reporting() & $errno)) {
// This error code is not included in error_reporting, so let it fall
// through to the standard PHP error handler
return false;
}
// Supported error types
$php_error_types = [
E_WARNING => 'E_WARNING',
E_NOTICE => 'E_NOTICE',
E_USER_ERROR => 'E_USER_ERROR',
E_USER_WARNING => 'E_USER_WARNING',
E_USER_NOTICE => 'E_USER_NOTICE',
E_RECOVERABLE_ERROR => 'E_RECOVERABLE_ERROR',
E_DEPRECATED => 'E_DEPRECATED',
E_USER_DEPRECATED => 'E_USER_DEPRECATED',
E_ALL => 'E_ALL'
];
$error_content = '<p><b>' . $php_error_types["$errno"] . '</b></p>' . $errstr . '</pre>';
$error_content .= '<p>The error occurred on line <b>' . $errline . '</b> in file: </p><pre>' . $errfile . '</pre>';
$error_content .= '<p><i>PHP ' . PHP_VERSION . ' (' . PHP_OS . ')</i></p>';
$error_content .= '<p>This should not happen. Ideally all <i>notices</i>, <i>warnings</i>, and <i>errors</i> should be handled in your code. To avoid this:</p>';
$error_content .= '<ol>
<li>Always define variables before you use them.</li>
<li>Remember to check that a file exists before including it.</li>
<li>Always handle potential errors according to coding standards. I.e. Show a relevant error to the user, fail silently, or log events to a file on the server.</li>
</ol>';
$error_content .= '<p class="indent"><b>Note.</b> The above is probably not a complete list.</p>';
echo $error_content;
/* Do not execute PHP internal error handler */
return true;
}
2. Finally, to define this as your new error handler, simply call set_error_handler like so:
set_error_handler('error_handler');
How is a custom error handler useful
A custom error handler is useful when you want to perform cleanup after an error occurs. An example of such clean up would be deleting files in an applications temp directory, although it might be best to handle clean up outside of PHP in order to make sure that it is actually done.
It is also a useful way to help developers fix common coding problems, such as misspelling a variable name or trying to include a file that does not exist, and even to catch non-fetal errors handled in your own code.
Many E_NOTICE and E_WARNING types will often be caused by novice developers, and they will be left scratching their heads as to why code is failing. Some of these can easily happen due to simple permission issues in Linux, or if a file that was supposed to exist suddenly does not. The problem is, code will silently fail without helping developers find track the issue. You need to know where to look.
Enforcing good coding practices can help avoid these issues. For example, if you are using OOP, you can more easily enforce good coding practices across a big project, such as not using or validating superglobals all over the place, and instead rely more on Don't Repeat Yourself (DRY). A custom error handler can be used in a similar way, as it allows you to "force" developers to follow good coding practices, such as avoiding E_NOTICE errors.
If you have a policy of not allowing E_NOTICE and E_WARNING, you can easily block the developer from progressing further, before the problem with their code is fixed.
Error types that are handled
- E_WARNING
- E_NOTICE
- E_USER_ERROR
- E_USER_WARNING
- E_USER_NOTICE
- E_RECOVERABLE_ERROR
- E_DEPRECATED
- E_USER_DEPRECATED
- E_ALL
Note. If E_ALL is used, only supported non-fetal errors will be handled.
Error types that are not handled
The following error types will not be caught by a custom error handler:
- E_ERROR
- E_PARSE
- E_CORE_ERROR
- E_CORE_WARNING
- E_COMPILE_ERROR
- E_COMPILE_WARNING
- E_STRICT
Links
- Predefined Error Constants - php.net
- set_error_handler - php.net
Tell us what you think: