17

I have a simple custom error handler that writes in a error log file some useful debug infos.

it's work for everything but it's not get triggered for FATAL error.

Any way to solve this?

Currently to bypass this circumstance I have registered a shutdown function too that checks error_get_last()

2

4 Answers 4

26

Nope, that's just a limitation of set_error_handler(); it doesn't handle all errors.

The following error types cannot be handled with a user defined function: E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING, and most of E_STRICT raised in the file where set_error_handler() is called.

The register_shutdown_function() and error_get_last() is a decent workaround.

1
  • Can you give example of using register_shutdown_function() and error_get_last() as workaround i can't think of one. Commented Nov 21, 2016 at 20:57
5

There are only hackish ways to solve it, e.g. by using register_shutdown_function() and then checking if an error occurred inside that function.

PHP has log_errors for a reason, you can make PHP log any error to syslog or a logfile without a single line of custom code. So using set_error_handler() for this purpose is not needed at all and should be avoided unless you need e.g. a stacktrace.

1
  • of course I need stacktrace and/or other debug infos as descrived in my first post
    – dynamic
    Commented Dec 15, 2011 at 23:16
4

As others have pointed out we can use register_shutdown_function() and error_get_last() in following fashion.

The below implementation will catch the errors which are not even caught by \Throwable as tested in php 7.1. It should work for previous PHP versions too. It should only be implemented in your development environment(by just adding it in your development config file) and shouldn't be done in production environment.

Implementation

register_shutdown_function(function () {
    $err = error_get_last();
    if (! is_null($err)) {
        print 'Error#'.$err['message'].'<br>';
        print 'Line#'.$err['line'].'<br>';
        print 'File#'.$err['file'].'<br>';
    }
});

Example Error

Error# Class Path/To/MyService contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Path/To/MyServiceInterface::add)
Line# 12
File# Path/To/MyService.php
2
  • is there a way to resume code a fatal error happened? for an error says some function is not defined. i want to define that function using eval() and resume my code to the next error. is that possible? Commented Jul 29, 2020 at 19:05
  • @AhmadAmeri Unfortunately, there is no way to continue after fatal error has occurred in PHP. You only can catch them through this hack and systematically remove them as and when they occur.
    – Kamal Soni
    Commented Jul 31, 2020 at 2:32
0

See https://www.php.net/manual/en/language.errors.php7.php

Most fatal errors can be handled with try catch finally or with ser_exception_handler

Example:

<?php

class A{
    public static $a=1;
}
try {
    unset(A::$a);
    
} catch(\Error $e){
    echo 'hello';
}

But this does not mean that this applies to all errors. For example, through try catch you will not catch errors E_WARNING, E_NOTICE, E_DEPRECATED or errors caused by the trigger_error function, but these errors are easily handled through set_error_handler.

Not the answer you're looking for? Browse other questions tagged or ask your own question.