Обработка ошибок PHP в производстве с помощью веб-сайта на основе Symfony 2


Мы запускаем несколько веб-сайтов symfony2 в производстве, и мы используем как Airbrake, так и Sentry для сбора исключений. Реальные исключения хорошо работают даже в рабочей среде, мы можем регистрировать их с большим количеством контекста, и мы можем показать пользователю красивую страницу с 500 ошибками.

Ошибки PHP - это совсем другая история. Я могу зарегистрировать их в Sentry, используя обработчик "при выключении", но, используя его, я не могу передать много контекста. Для пользователя также существует только пустая ошибка 503. Это отстой потому что мы не можем показать пользователю "следующий" шаг на случай, если что-то пошло не так.

Исходя из фона Java, мне очень нравятся "реальные" исключения, и в режиме разработки есть класс, который преобразует множество ошибок в исключения, но нет документированного или очевидного способа включить это в производство, поэтому я думаю, что, возможно, мне не стоит больше спрашивать;)

Как вы, ребята, справляетесь с этим, и какое это влечет за собой снижение производительности?

Это перекрестный пост от: http://groups.google.com/group/symfony2/browse_thread/thread/6129f57a35d8cb90?hl=en

Author: Roderik, 2012-05-14

4 answers

  • вы должны обрабатывать все свои "ошибки" как исключения
  • вы должны отправить правильный код заголовка http и перехватить эти коды ошибок http на веб-сервере: http://wiki.nginx.org/HttpFastcgiModule#fastcgi_intercept_errors (в apache тоже есть что-то подобное)
  • обработчик завершения работы вам нужен только для регистрации "фатальных" вещей
  • "контекст" в "функции выключения" не ограничен (если вы "выделяете" его до ошибки!)
  • Лучшая оптимизация - это не делать ошибки;)

Способ PHP включить это:

  1. Ошибки (начальная загрузка!):

    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. Исключения (класс обработчика исключений):

    set_exception_handler(array($this, 'exception'));
    
    public function exception(\Exception $e) {
        $this->logger->log($e);
    }
    
  3. Неустранимые ошибки (класс обработчика исключений):

    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']));
        }
    }
    

Это -PHP-путь™. Вся ваша обработка ошибок "Symfony2™" должна оставаться прежней.

 8
Author: cryptocompress, 2012-05-14 20:15:02

В Symfony2 мы можем ввести службу прослушивания ошибок/исключений (которая улавливает все ошибки), а в onKernelException() мы можем включить всю логику нашего домена для обработки ошибок/исключений.

 1
Author: Ritesh Aryal, 2013-10-30 12:41:55

Предполагая, что вы используете по крайней мере Symfony 2.3, существует новый механизм.

use Symfony\Component\Debug\ErrorHandler;

require_once __DIR__.'/../app/bootstrap.php.cache';
require_once __DIR__.'/../app/AppKernel.php';

// we need to register the Error Handler in order
// to get fatal errors delivered as Exceptions
ErrorHandler::register();

[...]
 1
Author: kepakiano, 2014-03-27 16:50:23

Вы можете добавить обработчик событий к некоторым событиям ядра (исключение, onResponse ....)

 0
Author: Thomas Decaux, 2012-09-06 12:24:56