<?php
namespace Lightbulb\Symfony\EventSubscriber;
use Lightbulb\Symfony\Exception\ApiErrorException;
use Lightbulb\Symfony\HttpFoundation\Response\AbstractErrorResponse;
use Lightbulb\Symfony\HttpFoundation\Response\ErrorResponseFactory;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
class ApiErrorResponseSubscriber implements EventSubscriberInterface
{
private LoggerInterface $logger;
/**
* ApiErrorResponseSubscriber constructor.
*
* @param LoggerInterface $logger
*/
public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
}
/**
* {@inheritDoc}
*/
public static function getSubscribedEvents(): array
{
return [
KernelEvents::RESPONSE => 'onKernelResponse',
KernelEvents::EXCEPTION => 'onKernelException',
];
}
/**
* Convert non standardized error responses to standardized.
*
* @param ResponseEvent $event
*/
public function onKernelResponse(ResponseEvent $event): void
{
if (in_array('application/json', $event->getRequest()->getAcceptableContentTypes())) {
$response = $event->getResponse();
if (false === $response->isSuccessful() && (false === $response instanceof AbstractErrorResponse)) {
$event->setResponse(ErrorResponseFactory::createFromResponse($response));
}
}
}
/**
* Sets a standardized error response on throwable.
*
* @param ExceptionEvent $event
*/
public function onKernelException(ExceptionEvent $event): void
{
$this->logger->error($event->getThrowable()->getMessage());
$this->logger->debug($event->getThrowable()->getTraceAsString());
if ($event->getThrowable() instanceof ApiErrorException) {
$event->setResponse($event->getThrowable()->getErrorResponse());
} elseif (in_array('application/json', $event->getRequest()->getAcceptableContentTypes())) {
$event->setResponse(
ErrorResponseFactory::createFromThrowable($event->getThrowable())
);
}
}
}