<?php
namespace Api\EventListener;
use App\Entity\Central\Client\Client;
use App\Entity\Client\PointOfSale\PointOfSale;
use App\Entity\Client\Store\Store;
use App\Service\AppManager;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Symfony\Component\HttpKernel\KernelInterface;
class ExceptionListener
{
private $kernel;
private $logger;
private $appManager;
public function __construct(KernelInterface $kernel, LoggerInterface $logger, AppManager $appManager)
{
$this->appManager = $appManager;
$this->kernel = $kernel;
$this->logger = $logger;
}
/**
* @param ExceptionEvent $event
*/
public function onKernelException(ExceptionEvent $event)
{
$exception = $event->getThrowable();
$response = $this->createApiResponse($exception);
if ($response instanceof JsonResponse){
$event->setResponse($response);
}
}
/**
* @param \Throwable $throwable
* @return JsonResponse
*/
private function createApiResponse(\Throwable $throwable)
{
$statusCode = $throwable instanceof HttpExceptionInterface ? $throwable->getStatusCode() : Response::HTTP_INTERNAL_SERVER_ERROR;
$data = ['error' => !$throwable instanceof HttpExceptionInterface && !$this->kernel->isDebug() ? 'Internal server error' : $throwable->getMessage()];
if ($this->kernel->isDebug()){
$data['backtrace'] = $throwable->getTrace();
}
if ($statusCode === 500){
$context = ['exception' => $throwable->getTraceAsString()];
if ($this->appManager->getClient() instanceof Client){
$context['client'] = $this->appManager->getClient()->__toString();
}
if ($this->appManager->getStore() instanceof Store){
$context['store'] = $this->appManager->getStore()->__toString();
}
if ($this->appManager->getPointOfSale() instanceof PointOfSale){
$context['point_of_sale'] = $this->appManager->getPointOfSale()->getName();
}
$this->logger->critical($throwable->getMessage(), $context);
}
return new JsonResponse(json_encode($data), $statusCode, [], true);
}
}