Skip to content

Instantly share code, notes, and snippets.

@earlpeterg
Last active October 7, 2022 04:50
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save earlpeterg/f7afe32d514156648c1e56c40aa08626 to your computer and use it in GitHub Desktop.
Save earlpeterg/f7afe32d514156648c1e56c40aa08626 to your computer and use it in GitHub Desktop.
WordPress Error Handler with debug backtrace
<?php
/*
Plugin Name: WordPress Error Handler
Description: An error handler with backtrace (not just for fatal errors).
Author: Earl Peter G
Author URI: https://www.earlpeter.com
Version: 0.3
License: Licensed under the Apache License, Version 2.0
http://www.apache.org/licenses/LICENSE-2.0
*/
// define( 'WP_DEBUG', true ); // Set to enable
// define( 'WP_DEBUG_DISPLAY', true ); // Set to display errors and warnings
// define( 'WP_DEBUG_LOG', true ); // Set to log errors and warnings
// Do not access file directly!
if (!defined('WPINC')) { die; }
if (!class_exists ('EarlPeter_WP_Error_Handler')) {
class EarlPeter_WP_Error_Handler {
public static function handleError($errno, $errstr, $errfile, $errline, $errcontext) {
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;
}
// These are default values for a single trace
// To prevent errors when a trace ommits some values
$defaults = ['line' => '', 'file' => '', 'class' => '', 'function' => ''];
$errfile = self::cleanFilePath($errfile);
$errname = self::errorCodeToString($errno);
$out = "\n$errname ($errno): $errstr\n";
$out .= "#0 <b>{main}</b> at $errfile:$errline\n";
$trace = debug_backtrace();
// skip current function and require() in /index.php
for($i = 1; $i < count($trace) - 1; $i++) {
$sf = (object)shortcode_atts($defaults, $trace[$i]);
$index = $i;
$file = self::cleanFilePath($sf->file);
$caller;
if(!empty($sf->class) && !empty($sf->function))
$caller = $sf->class . "::" . $sf->function . "()";
elseif(!empty($sf->function))
$caller = $sf->function . "()";
else
$caller = "{main}";
$out .= "#$index <b>$caller</b> at $file:{$sf->line}\n";
}
if (WP_DEBUG_DISPLAY) echo nl2br($out);
if (WP_DEBUG_LOG) error_log($out);
return true;
}
/**
* Removes root path of WordPress from a given directory.
* @param string $path
* @return string
*/
private static function cleanFilePath($path){
return str_replace(ABSPATH, '/', $path);
}
/**
* Gets the equivalent error code in string
* @param int $code
* @return string
*/
private static function errorCodeToString($code) {
$errors = array(
1 => 'ERROR',
2 => 'WARNING',
4 => 'PARSE',
8 => 'NOTICE',
16 => 'CORE ERROR',
32 => 'CORE WARNING',
64 => 'COMPILE ERROR',
128 => 'COMPILE WARNING',
256 => 'USER ERROR',
512 => 'USER WARNING',
1024 => 'USER NOTICE',
2048 => 'STRICT',
4096 => 'RECOVERABLE ERROR',
8192 => 'DEPRECATED',
16384 => 'USER DEPRECATED',
);
if (isset($errors[$code])) return $errors[$code];
else return 'UNKNOWN ERROR';
}
}
if (WP_DEBUG) set_error_handler('EarlPeter_WP_Error_Handler::handleError');
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment