DebugBundle - отключаем

Столкнулся с проблемой - объявил в конструкторе ResponseListener-а зависимость в виде LoggerInterface и получил ошибки, которая съела всю память, при этом выводя все в stdout уронила браузер. Исследовав проблему, понял что виной тому stopwatch который входит в состав DebugBundle. Я решил попробовать отключить его в config/bundles.php. Однако, Symfony начала ругаться:

Container extension "debug" is not registered.

Поэтому, пошел в config/packages/debug.yaml и закомментировал все строки, а именно:

#when@dev:
#    debug:
#        # Forwards VarDumper Data clones to a centralized server allowing to inspect dumps on CLI or in your browser.
#        # See the "server:dump" command to start a new server.
#        dump_destination: "tcp://%env(VAR_DUMPER_SERVER)%"

Как итог - возможно теперь при некоторых проблемах красивое отображением ошибки пропало: 

но, профайлер остался и работает как и раньше:

Дополнительно сделал ошибку в Twig-шаблоне и получил красивую страницу с ошибкой:

Так зачем мне нужен этот дебаг-компонент. Идем дальше, делаю ошибку в инъекции:

    YaPro\SeoBundle\NoindexNofollowResponseListener:
        arguments:
            - "Psr\Log\LoggerInterface"

Опять получаю ошибку, которая съела всю память и при выводе в stdout уронила браузер.

Исследовав проблему, понял что виной тому тот, кто распечатывает ошибку (найти сходу не удалось, может как-нибудь потом). Важно то, что эта ошибка является объектом, который имеет большую вложенность и объекты ссылающиеся друг на другу по кругу. Это хорошо видно потому, что распечатываемые данные выглядят не естественным для PHP образом.

Как же чинить

Присмотревшись видно, что при любой пхп ошибке \Symfony\Component\HttpKernel\HttpKernel::handleThrowable вызывает $this->dispatcher->dispatch($event, KernelEvents::EXCEPTION); а тот в свою очередь вызывает Symfony\Component\HttpKernel\Debug\TraceableEventDispatcher, который снова пробегает по слушателям и в методе dispatch вызывает снова: $this->afterDispatch($eventName, 'kernel.exception');

Все это выглядит так, словно нужно отключить обработку события 'kernel.exception'. Напомню, все события перечислены в \Symfony\Component\HttpKernel\KernelEvents

Но, какого-либо способа выключить kernel.exception не существует, однако можно игнорировать событие. 

 

Создаем свой EventDispatcher в виде декоратора event_dispatcher:

    App\Service\ErrorEventDispatcher:
        decorates: 'event_dispatcher'
        decoration_priority: -500000

в котором пишем такой метод обработки событий:

    public function dispatch(object $event, ?string $eventName = null): object
    {
        if ($eventName === 'kernel.exception') {
            return $event;
        }

        return $this->decorated->dispatch($event,$eventName);
    }

Проверяем, что переопредить удалось: bin/console debug:container 'event_dispatcher'

Вот и все, теперь получаем ошибку распечатанную PHP (которая не съедает всю память):

Единственная проблема в том, что профайлер тоже перестает работать, так не пойдет.

Поэтому, мы попробуем отключить ErrorListener (DI знает его как сервис exception_listener и console.error_listener).

Переопределяем:

    App\Service\RealErrorListener:
        decorates: 'exception_listener'
        decoration_priority: -500000

Содержимое:

<?php
declare(strict_types=1);

namespace App\Service;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class RealErrorListener implements EventSubscriberInterface
{
    public static function getSubscribedEvents()
    {
        return []; //$this->decorated->getSubscribedEvents();
    }
}

Проверяем: bin/console debug:container 'exception_listener'

Эффект такой же, как от переопределения EventDispatcher - профайлер не работает.

Итог: надо продолжать копать дальше в сторону декорации ErrorListener, но пока времени нет.


11.09.2021 07:08

Комментарии

Комментариев пока нет.


Copyrights © 2007 - 2026 YaPro.Ru