<?php
declare(strict_types=1);
namespace App\System\Exception\Listener;
use ApiPlatform\Core\Bridge\Symfony\Validator\Exception\ValidationException;
use ApiPlatform\Core\Exception\ItemNotFoundException;
use App\Infrastructure\Interfaces\Logger\MessageDirectorInterface;
use App\Infrastructure\Interfaces\Logger\NetworkLoggerInterface;
use App\System\Infrastructure\Implementation\ApiException\ApiException;
use App\System\Infrastructure\Implementation\Logger\Exceptions\ExceptionBuilder;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Serializer\SerializerInterface;
class ExceptionListener implements EventSubscriberInterface
{
private const EXCLUDED_EXCEPTIONS = [
ValidationException::class,
NotFoundHttpException::class,
ItemNotFoundException::class,
AccessDeniedHttpException::class,
ApiException::class,
];
public function __construct(
private readonly NetworkLoggerInterface $networkLogger,
private readonly MessageDirectorInterface $messageDirector,
private readonly SerializerInterface $serializer,
) {
}
public function onKernelException(ExceptionEvent $event)
{
$exception = $event->getThrowable();
if (!in_array(get_class($exception), self::EXCLUDED_EXCEPTIONS)) {
$builder = new ExceptionBuilder();
$builder->setException($exception);
$this->messageDirector->setMessageBuilder($builder);
$this->networkLogger->publish($this->messageDirector);
}
$httpCode = 500;
if ($exception instanceof HttpExceptionInterface) {
$httpCode = $exception->getStatusCode();
}
if ($exception instanceof ApiException) {
$httpCode = $exception->getCode();
}
$msg = $this->serializer->serialize($exception, 'json');
$event->setResponse(new JsonResponse($msg, $httpCode, json: true));
}
public static function getSubscribedEvents(): array
{
return [
KernelEvents::EXCEPTION => 'onKernelException',
];
}
}