Ideally I would like to log the user or page that triggers a fatal error so that I can follow up with that person or go directly to the page they were on for testing. My thought is that if there is an action hook or filter that I can tap into during the logging process, I might be able to achieve this. I don't know if it would work, but it would help speed up the debugging process. Any suggestions are appreciated. Thanks in advance.
2 Answers
Look into the WP_Fatal_Error_Handler
class. I see a couple of filters in its display_default_error_template()
method that might be helpful for you:
The entire class is a drop-in, so if you need to you can replace it entirely with your own version, but I think one of those filters—probably wp_php_error_args
—might be what you're looking for.
-
-
This unfortunately did not work for me. Tried both filters. I did however figure it out using
set_error_handler()
instead of trying to find a hook (I posted my answer). It works as I hoped and logs the user id, user display name, and the url with query strings. Thanks for looking into it, though. Commented May 22, 2023 at 17:51
I figured it out with set_error_handler()
rather than a hook:
/**
* Add user and url when an error occurs
*
* @param int $num
* @param string $str
* @param string $file
* @param string $line
* @param null $context
* @return void
*/
function ddtt_log_error( $num, $str, $file, $line, $context = null ) {
// Get user id
$user_id = get_current_user_id();
// Check for a user name
if ( is_user_logged_in() ) {
$user = get_userdata( $user_id );
$display_name = sanitize_text_field( $user->display_name );
} else {
$display_name = 'Visitor';
}
// Log
error_log( 'Error triggered by user '.$user_id.' ('.$display_name.') on '.$_SERVER[ 'REQUEST_URI' ] );
// Restore the old handler
restore_error_handler();
} // End ddtt_log_error()
set_error_handler( 'ddtt_log_error' );
/**
* Checks for fatal errors and parse errors, work around for set_error_handler not working on them.
*
* @return void
*/
function ddtt_check_for_fatal() {
$error = error_get_last();
$additional_errors = [ E_ERROR, E_PARSE ];
if ( isset( $error[ 'type' ] ) && in_array( $error[ 'type' ], $additional_errors ) ) {
ddtt_log_error( $error[ 'type' ], $error[ 'message' ], $error[ 'file' ], $error[ 'line' ] );
}
} // End ddtt_check_for_fatal()
register_shutdown_function( 'ddtt_check_for_fatal' );