Code Coverage
 
Lines
Branches
Paths
Functions and Methods
Classes and Traits
Total
69.23% covered (warning)
69.23%
9 / 13
7.69% covered (danger)
7.69%
1 / 13
12.50% covered (danger)
12.50%
1 / 8
33.33% covered (danger)
33.33%
1 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
ExceptionSubscriber
69.23% covered (warning)
69.23%
9 / 13
7.69% covered (danger)
7.69%
1 / 13
12.50% covered (danger)
12.50%
1 / 8
33.33% covered (danger)
33.33%
1 / 3
39.83
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 onExceptionEvent
88.89% covered (warning)
88.89%
8 / 9
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
5.03
 getSubscribedEvents
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace App\Shared\Infrastructure\EventSubscriber;
4
5use Symfony\Component\DependencyInjection\Attribute\AutowireIterator;
6use Symfony\Component\EventDispatcher\EventSubscriberInterface;
7use Symfony\Component\HttpFoundation\JsonResponse;
8use Symfony\Component\HttpKernel\Event\ExceptionEvent;
9use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
10use Symfony\Component\HttpKernel\KernelEvents;
11use Symfony\Component\Serializer\Exception\ExceptionInterface;
12use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
13
14/**
15 * Handles exceptions to generate Json responses using custom normalizers
16 * This allows more control on the error response format with no dependency to symfony internals
17 *
18 * @author Wilhelm Zwertvaegher
19 *
20 */
21readonly class ExceptionSubscriber implements EventSubscriberInterface
22{
23    /**
24     * @param iterable<NormalizerInterface> $normalizers
25     */
26    public function __construct(
27        #[AutowireIterator('app.exception_normalizer')]
28        private iterable $normalizers
29    ) {
30    }
31
32    /**
33     * @throws ExceptionInterface
34     */
35    public function onExceptionEvent(ExceptionEvent $event): void
36    {
37        $request = $event->getRequest();
38        if ($request->getRequestFormat() !== 'json') {
39            return;
40        }
41        $throwable = $event->getThrowable();
42        foreach ($this->normalizers as $normalizer) {
43            if ($normalizer->supportsNormalization($throwable)) {
44                $data = $normalizer->normalize($throwable);
45                $status = $data['status'] ?? ($throwable instanceof HttpExceptionInterface ? $throwable->getStatusCode() : 500);
46                $event->setResponse(new JsonResponse($data, $status));
47            }
48        }
49    }
50
51    public static function getSubscribedEvents(): array
52    {
53        return [
54            KernelEvents::EXCEPTION => 'onExceptionEvent',
55        ];
56    }
57}