New error handler for API.

This commit is contained in:
2024-10-16 20:05:26 +02:00
parent 1bf738be1c
commit facd5bc9c0
3 changed files with 178 additions and 0 deletions
@@ -0,0 +1,67 @@
<?php
namespace App\EventSubscriber;
use App\ApiErrorException;
use App\DTO\ApiErrorMessage;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
class ApiExceptionSubscriber implements EventSubscriberInterface
{
public function __construct(
private LoggerInterface $logger,
) {}
public function onKernelException(ExceptionEvent $event): void
{
$e = $event->getThrowable();
if ($e instanceof ApiErrorException) {
$apiErrorMsg = $e->getApiErrorMsg();
} else {
$statusCode = $e instanceof HttpExceptionInterface ? $e->getStatusCode() : 500;
$apiErrorMsg = new ApiErrorMessage($statusCode);
/*
* If it's an HttpException message (e.g. for 404, 403),
* we'll say as a rule that the exception message is safe
* for the client. Otherwise, it could be some sensitive
* low-level exception, which should *not* be exposed
*/
if ($e instanceof HttpExceptionInterface) {
$apiErrorMsg->setExtraData('detail', $e->getMessage());
}
}
//Send error to logs.
$exceptionError = [
'message' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'trace' => $e->getTrace()
];
$errorContext = array_merge($apiErrorMsg->toArray(), $exceptionError);
$this->logger->error("API ERROR Exception:", $errorContext);
//Send error to client.
$response = new JsonResponse(
$apiErrorMsg->toArray(),
$apiErrorMsg->getStatusCode()
);
$response->headers->set('Content-Type', 'application/problem+json');
$event->setResponse($response);
}
public static function getSubscribedEvents(): array
{
return [
KernelEvents::EXCEPTION => 'onKernelException',
];
}
}