Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Factoring fatal error handling out of flush function #18

Merged
merged 4 commits into from Apr 14, 2014
Merged

Factoring fatal error handling out of flush function #18

merged 4 commits into from Apr 14, 2014

Conversation

ghost
Copy link

@ghost ghost commented Mar 20, 2014

Our team are using this library to catch errors and report them to Rollbar, but only on certain environments. On others, we use different reporting methods. As such, we use our own error handler which sits in front of Rollbar, and passes on any errors it catches to Rollbar where appropriate. This is easy to do as we can pass false as the second and third parameters of the Rollbar::init() function to prevent it from registering it's own error and exception handlers.

The only problem with this approach is that this doesn't apply to fatal errors - there is no way currently to stop the Rollbar object from intercepting and reporting fatal errors independently. Another issue is that fatal errors are only reported if batching is switched on.

Fortunately, register_shutdown_function is stackable, meaning we can register multiple functions to run in order at shutdown. As such, I've split the fatal error catching code out from the Rollbar::flush() function, and added an extra parameter to the end of the Rollbar::init() function, mimicking the behaviour of the other two handlers.

Potential Gotcha: Registered shutdown functions are called in the order they were registered

Provided our own shutdown function is registered before the Rollbar library is initialized, E_ERROR will be reported:

class Custom_Error_Handler {
    public static function init() {
        set_exception_handler('Custom_Error_Handler::process_exception');
        set_error_handler('Custom_Error_Handler::process_error');
        register_shutdown_function('Custom_Error_Handler::catch_fatal_error');
        Rollbar::init(array(/* rollbar token etc */), false, false, false);
    }

    public static function process_exception(Exception $exc) {

        // ...

        Rollbar::report_exception($exc);
    }

    public static function process_error($errno, $errmsg, $errfile, $errline) {

        // ...

        Rollbar::report_php_error($errno, $errmsg, $errfile, $errline);
    }

    public static function catch_fatal_error() {
        $last_error = error_get_last();
        if(!is_null($last_error) && $last_error['type'] == E_ERROR) {
            self::process_error($last_error['type'], $last_error['message'], $last_error['file'], $last_error['line']);
        }
    }
}

Custom_Error_Handler::init();

$not_an_object = 'just a string';
$not_an_object->not_a_method(); // Generates E_ERROR
/*
Registered shutdown functions fire in the order they were registered:

    Custom_Error_Handler::catch_fatal_error() fires
    Rollbar::report_fatal_error() wasn't registered, because we passed in false
    Rollbar::flush() fires (assuming the library is in batch mode), and sends the error to Rollbar
*/

Note that if Rollbar was initialized before Custom_Error_Handler::catch_fatal_error was registered as a shutdown function, the final Rollbar::flush() will occur before our catch_fatal_error has passed the error on to the Rollbar object. In this situation, in batch mode, the error may not be reported to the Rollbar API.

Backwards compatibility

Like the other two parameters, the new parameter has a default value of true, so should be backwards compatible, and also solves the issue of fatal errors not being reported when batched mode is not being used.

@sbezboro sbezboro merged commit 29b2b17 into rollbar:master Apr 14, 2014
@sbezboro
Copy link
Contributor

Looks good to me, thanks! Merged and released as version 0.8.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant