0
votes

Abonné d'exception Symfony non déclenché

J'ai besoin de formater les messages d'erreur et de les afficher au format JSON.

J'ai l'abonné d'événement suivant:

class FooBar {
    public __constructor(NonExistingService $service) {/*..*/}
}

Et la configuration suivante dans ./ config / services.yaml

services:
    _defaults:
        autowire: true
        autoconfigure: true

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

Cet abonné à l'événement fonctionne lorsque par exemple le contrôleur génère une erreur.

Mais si j'ai une autre erreur, par exemple mauvaise injection DI

namespace App\EventSubscriber;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\KernelEvents;

final class ExceptionSubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents(): array
    {
        return [KernelEvents::EXCEPTION => 'onKernelException'];
    }

    public function onKernelException(ExceptionEvent $event) {/*..*/}
}

alors la sortie est toujours au format Html et en tant que page d'erreur Symfony.


Comment faire que toute erreur détectée par Symfony est converti via ma classe en JSON?


0 commentaires

3 Réponses :


0
votes

Je ne sais pas si c'est ce à quoi vous faites référence, mais assurez-vous de définir correctement la réponse:

    public function onKernelException(ExceptionEvent $event): void
    {
        $exception = $event->getThrowable();

        $response = new JsonResponse(
            ['error'],
            Response::HTTP_INTERNAL_SERVER_ERROR,
            [
                'Content-Type' => 'application/vnd.api+json',
            ]
        );

        $event->setResponse($response);
    }


2 commentaires

onKernelException n'est même pas appelé. La première phrase il y a echo "OK"; die ();


La documentation Symfony indique que TwigBundle enregistre un Symfony \ Component \ HttpKernel \ EventListener \ ExceptionListener qui transmet la requête à un contrôleur donné défini par le paramètre exception_listener.controller. . Peut-être que cela a quelque chose à voir avec cet abonné? symfony.com/doc/current/reference/events.html#kernel- sauf le



0
votes

Vous pouvez remplacer le contrôleur d'erreur par défaut dans la configuration.

Consultez la documentation ici: https: // symfony.com/doc/current/controller/error_pages.html#overriding-the-default-errorcontroller


0 commentaires

0
votes

J'ai trouvé ce qui ne va pas ici.

Le problème est que si vous avez par exemple erreur de configuration, vos événements ne seront pas encore connectés.

Dans mon code, j'ai ceci:

namespace App\Error;

use Symfony\Component\ErrorHandler\BufferingLogger;
use Symfony\Component\ErrorHandler\Debug as SymfonyDebug;
use Symfony\Component\ErrorHandler\ErrorHandler;

class Debug extends SymfonyDebug
{
    public static function enable(): ErrorHandler
    {
        if ($_SERVER['APP_DEBUG']) {
            umask(0000);

            $errorHandler = parent::enable();
        }

        return self::setDefaultErrorHandler($errorHandler ?? null);
    }

    private static function setDefaultErrorHandler(?ErrorHandler $errorHandler): ErrorHandler
    {
        $errorHandler ??= ErrorHandler::register(new ErrorHandler(new BufferingLogger(), true));

        $errorHandler->setExceptionHandler([ExceptionHandler::class, 'renderException']);

        return $errorHandler;
    }
}

Ce Debug :: enable ( ) définit en fait le gestionnaire d'erreur (sans cela, il n'y a que le gestionnaire d'erreur PHP par défaut au démarrage).

J'ai étendu Debug avec ma propre classe:

// index.php

if ($_SERVER['APP_DEBUG']) {
    umask(0000);

    $errorHandler = Debug::enable();
}

$kernel = new Kernel();
/* .. */


Désormais, toutes les erreurs passent par mon App \ Error \ ExceptionHandler où je peux l'afficher sous la forme JsonResponse


0 commentaires