Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling PHP errors in production with a Symfony 2 based website

We are running several symfony2 websites in production and we are using both Airbrake and Sentry to collect exceptions. Real exceptions are working nicely even in production, we can log them with a lot of context, and we can show to user a nice 500 error page.

PHP errors are a different story. I can log them to Sentry using a "on shutdown" handler, but using this I cannot pass along a lot of context. For the user there is also only an empty 503 error. This sucks because we cannot show the user a "next" step in case something went wrong.

Coming from a Java background i quite like "real" exceptions and in development mode there is a class that converts a lot of errors in exceptions, but there is no documented or obvious way of enabling this in production, so I figure maybe I shouldn't before asking around some more ;)

How are you guys handling this, and what kind of performance penalty does it entail?

This is a crosspost from: http://groups.google.com/group/symfony2/browse_thread/thread/6129f57a35d8cb90?hl=en

like image 257
Roderik Avatar asked Dec 21 '22 21:12

Roderik


2 Answers

  • you should handle all your "errors" as exceptions
  • you should send right http header code and intercept this http error codes in webserver: http://wiki.nginx.org/HttpFastcgiModule#fastcgi_intercept_errors (there is something like this in apache too)
  • you need the shutdown handler only for logging "Fatal" things
  • "context" in "shutdown function" is not limited (if you "allocate" it before the error!)
  • Best optimization is not to do errors ;)

the PHP way to enable this:

  1. Errors (bootstrap!):

    set_error_handler('errorToException');
    
    function errorToException($code, $message, $file = null, $line = 0) {
        if (error_reporting() == 0) {
            return true;
        }
        throw new \ErrorException($message, $code, $file, $line);
    }
    
  2. Exceptions (ExceptionHandler class):

    set_exception_handler(array($this, 'exception'));
    
    public function exception(\Exception $e) {
        $this->logger->log($e);
    }
    
  3. Fatal Errors (ExceptionHandler class):

    register_shutdown_function(array($this, 'shutdown'));
    
    public function shutdown() {
        $error = error_get_last();
        if (isset($error)) {
            $this->exception(new \FatalException($error['message'], $error['type'],     $error['file'], $error['line']));
        }
    }
    

This is the-PHP-way™. All your "Symfony2™" ErrorHandling should stay the same.

like image 161
cryptocompress Avatar answered Dec 26 '22 16:12

cryptocompress


In Symfony2, we can introduce Error/Exception listener service (which catches all the errors) and on onKernelException() we can include all of our domain logic to handle error/exception.

like image 34
Ritesh Aryal Avatar answered Dec 26 '22 16:12

Ritesh Aryal