<?php
namespace Harmonizely\EventListener;
use Harmonizely\Core\Exception\BaseException;
use Harmonizely\Core\Exception\Contract\IBaseException;
use Harmonizely\Core\Exception\RedirectToRoute;
use Harmonizely\Core\Exception\UnexpectedException;
use Harmonizely\Core\Response\Contract\IResponseBuilder;
use Harmonizely\Service\UserLoginAttempt\Exception\AccessDeniedException as AccessDeniedExceptionUserLoginAttempt;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
class ExceptionListener
{
/**
* @var SessionInterface
*/
private SessionInterface $session;
/**
* @var UrlGeneratorInterface
*/
private UrlGeneratorInterface $urlGenerator;
/**
* @var IResponseBuilder
*/
private IResponseBuilder $responseBuilder;
/**
* @var LoggerInterface
*/
private LoggerInterface $logger;
/**
* @param SessionInterface $session
* @param UrlGeneratorInterface $urlGenerator
* @param IResponseBuilder $responseBuilder
* @param LoggerInterface $logger
*/
public function __construct(
SessionInterface $session,
UrlGeneratorInterface $urlGenerator,
IResponseBuilder $responseBuilder,
LoggerInterface $logger
)
{
$this->session = $session;
$this->urlGenerator = $urlGenerator;
$this->responseBuilder = $responseBuilder;
$this->logger = $logger;
}
/**
* Handle kernel exception event
*
* @param ExceptionEvent $event
*/
public function onKernelException(ExceptionEvent $event)
{
$exception = $event->getThrowable();
if ($exception instanceof IBaseException) {
$event->setResponse($this->responseBuilder->buildExceptionResponse($exception));
return;
}
if ($exception instanceof AccessDeniedExceptionUserLoginAttempt) {
$this->session->getFlashBag()->add('danger', $exception->getMessage());
$event->setResponse(new RedirectResponse($this->urlGenerator->generate('fos_user_security_login')));
return;
}
if ($exception instanceof RedirectToRoute) {
$event->setResponse(new RedirectResponse($this->urlGenerator->generate($exception->getRoute())));
return;
}
$this->logger->error('Exception occurred: ' . $exception->getMessage(), [
'exception' => $exception,
'trace' => $exception->getTraceAsString(),
]);
if ($exception instanceof UnexpectedException) {
$event->setResponse($this->responseBuilder->buildExceptionResponse(new BaseException($exception->getMessage())));
return;
}
}
}