<?php
namespace App\EventListener\Exception;
use ApiPlatform\Core\Bridge\Symfony\Validator\Exception\ValidationException;
use ApiPlatform\Core\Util\ErrorFormatGuesser;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\Serializer\SerializerInterface;
class ExceptionListener
{
private SerializerInterface $serializer;
private array $errorFormats;
public function __construct(SerializerInterface $serializer, array $errorFormats)
{
$this->serializer = $serializer;
$this->errorFormats = $errorFormats;
}
public function onKernelException(ExceptionEvent $event)
{
$exception = method_exists($event, 'getThrowable') ? $event->getThrowable() : $event->getException();
if (!$exception instanceof ValidationException) {
return;
}
$codesList = [];
$constraintList = $exception->getConstraintViolationList();
foreach ($constraintList as $k => $c) {
$codesList[$k] =
$c->getCode() ??
hash("md5", get_class($c->getConstraint()));
}
$format = ErrorFormatGuesser::guessErrorFormat($event->getRequest(), $this->errorFormats);
$serializedError = $this->serializer->serialize($constraintList, $format['key']);
$response = json_decode($serializedError, true);
foreach ($response["violations"] as $k => $v) {
$response["violations"][$k]["code"] = $codesList[$k];
}
$serializedError = json_encode($response);
$event->setResponse(new Response(
$serializedError,
Response::HTTP_BAD_REQUEST,
[
'Content-Type' => sprintf('%s; charset=utf-8', $format['value'][0]),
'X-Content-Type-Options' => 'nosniff',
'X-Frame-Options' => 'deny',
]
));
}
}