<?php
namespace App\EventListener;
use App\Security\AccessDeniedException;
use Doctrine\DBAL\Exception\DeadlockException;
use FOS\RestBundle\View\View;
use FOS\RestBundle\View\ViewHandler;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Twig\Environment;
/**
* Class ExceptionListener
* @package App\EventListener
* @since 0.18.6
*/
class ExceptionListener {
private ViewHandler $viewHandler;
private Environment $twig;
private LoggerInterface $logger;
public function __construct(ViewHandler $viewHandler, Environment $twig, LoggerInterface $logger) {
$this->viewHandler = $viewHandler;
$this->twig = $twig;
$this->logger = $logger;
}
public function onKernelException(ExceptionEvent $event) {
$exception = $event->getThrowable();
if ($exception instanceof AccessDeniedException) {
if ($event->getRequest()->getRequestFormat() === 'html') {
try {
$event->setResponse(
new Response(
$this->twig->render(
'error/access_denied.html.twig',
['messages' => $exception->getMessages()]
),
$exception->getCode()
)
);
return;
} catch (\Exception $e) {
$this->logger->error('Can not render access denied template', ['exception' => $e]);
}
}
$data = [
'message' => implode('. ', is_array($exception->getMessages()) ? $exception->getMessages() : [$exception->getMessages()]),
];
$event->setResponse($this->viewHandler->handle(View::create($data, $exception->getCode() ?: 400)));
}
if ($exception instanceof DeadlockException) {
$this->logger->error('Got deadlock exception', ['exception' => $exception]);
$event->setResponse(new Response('Resource locked. Retry request', 503));
}
}
}