Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handle fatal errors in PHP using register_shutdown_function()

According to the comment on this answer it is possible to catch Fatal Errors through a shutdown function which cannot be caught using set_error_handler().

However, I couldn't find out how to determine if the shutdown has occured due to a fatal error or due to the script reaching its end.

Additionally, the debug backtrace functions seem to be defunct in the shutdown function, making it pretty worthless for logging the stack trace where the Fatal Error occured.

So my question is: what's the best way to react on Fatal Errors (especially undefined function calls) while keeping the ability to create a proper backtrace?

like image 972
ThiefMaster Avatar asked Dec 10 '10 15:12

ThiefMaster


People also ask

How to catch fatal error in PHP?

You can "catch" these "fatal" errors by using set_error_handler() and checking for E_RECOVERABLE_ERROR. I find it useful to throw an Exception when this error is caught, then you can use try/catch.

What causes fatal error in php?

Fatal Error Fatal errors are ones that crash your program and are classified as critical errors. An undefined function or class in the script is the main reason for this type of error.

What would occur if a fatal error was thrown in your PHP program?

It's an error that caused the script to abort and exit immediately. All statements after the fatal error are never executed. I strongly recommend you use an editor that will alert you to errors as you code. It will safe you a lot of time.


2 Answers

This works for me:

function shutdown() {     $error = error_get_last();     if ($error['type'] === E_ERROR) {         // fatal error has occured     } }  register_shutdown_function('shutdown');  spl_autoload_register('foo');  // throws a LogicException which is not caught, so triggers a E_ERROR 

However, you probably know it already, but just to make sure: you can't recover from a E_ERROR in any way.

As for the backtrace, you can't... :( In most cases of a fatal error, especially Undefined function errors, you don't really need it. Pinpointing the file/line where it occured is enough. The backtrace is irrelevant in that case.

like image 142
netcoder Avatar answered Sep 25 '22 09:09

netcoder


One way to distinguish between fatal error and proper application shutdown with the register_shutdown_function is to define a constant as the last line of your program, and then check if the constant is defined:

function fatal_error() { if ( ! defined(PROGRAM_EXECUTION_SUCCESSFUL)) {         // fatal error has occurred     } }  register_shutdown_function('fatal_error');  define('PROGRAM_EXECUTION_SUCCESSFUL', true); 

If the program reaches the end, it could not have encountered a fatal error, so we know not to run the function if the constant is defined.

error_get_last() is an array with all the information regarding the fatal error that you should need to debug, though it will not have a backtrace, as has been mentioned.

Generally, if your php program has encountered a fatal error (as opposed to an exception), you want the program to blow up so you can find and fix the problem. I've found register_shutdown_function useful for production environments where you want error reporting off, but want some way to log the error in the background so that you can respond to it. You could also use the function to direct the user to a friendly html page in the event of such an error so that you don't just serve up a blank page.

like image 22
Gabriel Avatar answered Sep 22 '22 09:09

Gabriel