Search code examples
phptry-catch

PHP 7.4 unable to catch Fatal error: Cannot redeclare <function>


I loved the introduction of the \Throwable interface and the ability to convert legacy Errors warnings and notices into catchable errors.

This is how I have rolled ever since:

//convert errors to exceptions
set_error_handler(function ($severity, $message, $file, $line) {
    if (!(error_reporting() & $severity)) {
        // This error code is not included in error_reporting config so do nothing
        return;
    }
    throw new ErrorException($message, 0, $severity, $file, $line);
});

try {
   //application entry point
} catch (\Throwable $exception) {
    //consistent error response
}

However, some errors still can not be caught despite implementing all of these mechanisms.

Fatal error: Cannot redeclare some_function() (previously declared in <file:line>) in <file> on line <line>

This kind of thing is rare and really shouldn't happen but I still want to catch them somehow and provide a stack trace to devs with a constant error response.

Is this possible or do I just have to accept that even with modern PHP versions some errors still can not be caught?


Solution

  • Fatal errors cannot be caught, because they are FATAL, and they terminates execution. The only thing you can do is register shutdown function and log them:

    function catch_fatal()
    {
        $err = error_get_last();
    
        if ($err && $err['type'] === E_ERROR)
        {  
            // do something
        }
    }
    
    register_shutdown_function('catch_fatal');
    

    but this is anti-pattern and useless in most cases. In general, you should avoid any PHP-level errors (even E_NOTICE) in your application. If they happens, they should appear in standard engine logs, and be handled by monitoring solution you use

    Instead of showing messages for this errors from your app, you should setup this messages on upstream proxy (nginx, apache, etc) for HTTP codes 5xx