Maarduk
Maarduk

Reputation: 256

How to handle exceptions using events in Symfony 4?

Right now I'm trying to catch an exception event like that:

try {
    echo 1 / 0;
} catch (\Exception $e){
    $subs = new ExceptionSubscriber();
    $this->dispatcher->addSubscriber($subs);
};

I have defined ExceptionSubscriber which looks as follows:

class ExceptionSubscriber implements EventSubscriberInterface
{

    public static function getSubscribedEvents()
    {
        return [
            KernelEvents::EXCEPTION => [
                ['processException', 10],
                ['exception', -10],
            ],
        ];
    }

    public function exception(ExceptionEvent $event)
    {
        echo 'test321';
    }

    public function processException(ExceptionEvent $event)
    {
        echo 'test123';
    }
}

And this is my services.yaml

App\EventSubscriber\ExceptionSubscriber:
    tags:
        - { name: kernel.event_subscriber, event: kernel.exception }

I understand that regular PHP exception I'm catching is not one of the kernel exception events, in that case I have to create custom exception event, right?

The way I'm dispatching events using EventSubscriber, not listener is good

Do I have to dispatch those events or they are passed into subscriber in some magical way?

Upvotes: 3

Views: 10615

Answers (2)

yivi
yivi

Reputation: 47308

When an Exception is thrown (and it is not handled), the HttpKernel catches it and dispatches a kernel.exception event.

But in your example this would never happen, since you are catching the exception yourself. And are trying to create a subscriber there, which doesn't make a lot of sense; if anything you would be dispatching an event. But dispatching a new event is not necessary, since the kernel.exception event is already dispatched by the framework.

If you want to catch that event, you need to create your own Event Listener. A basic example:

class ExceptionListener
{
    public function onKernelException(ExceptionEvent $event)
    {
        $exception = $event->getException();

        // inspect the exception
        // do whatever else you want, logging, modify the response, etc, etc
    }
}

You would need to configure this class to actually listen to these events:

services:
    App\EventListener\ExceptionListener:
        tags:
            - { name: kernel.event_listener, event: kernel.exception }

There is nothing else to be done. Any uncaught exception will go through here. No need to create specific try/catch blocks (although they are a good idea in general terms, since handling your own exceptions is generally a good thing).

This is all explained in the docs in these places, among others:

Upvotes: 8

Code Spirit
Code Spirit

Reputation: 5041

Uncatched exceptions in controllers are catched by symfony which then constructs and dispatches the kernels exception event.
Actually you are not catching any exceptions, you are subscribing to an event. Symfony catches them and you receive an event with a method getException.
You can find more infos here: Symfony: How to Customize Error Pages

Upvotes: 1

Related Questions