<?php
namespace ApiV3Bundle\Listener;
use ApiV3Bundle\ApiV3Bundle;
use AppBundle\Common\ExceptionPrintingToolkit;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Throwable;
class ApiV3ExceptionListener
{
private $container;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
public function onKernelException(ExceptionEvent $event)
{
if (!$this->isApiPath($event->getRequest())) {
return;
}
$exception = $event->getThrowable();
$data = $this->buildResponseData($exception);
$statusCode = $this->getStatusCode($exception);
$response = new JsonResponse($data, $statusCode);
$event->setResponse($response);
$event->stopPropagation();
}
private function buildResponseData(Throwable $exception): array
{
$data = [
'status' => false,
'message' => 'Internal server error',
'code' => $exception->getCode() ?: 0,
];
if ($this->isDebug()) {
$data['message'] = $this->container->get('translator')->trans($exception->getMessage());
$data['trace'] = ExceptionPrintingToolkit::printTraceAsArray($exception);
} else if ($exception instanceof HttpExceptionInterface) {
$data['message'] = $this->container->get('translator')->trans($exception->getMessage());
} else {
$this->container->get('biz')->offsetGet('logger')->error('[V3Exception] ' . $exception->getMessage(), ExceptionPrintingToolkit::printTraceAsArray($exception));
}
return $data;
}
private function getStatusCode(Throwable $exception): int
{
if ($exception instanceof HttpExceptionInterface) {
return $exception->getStatusCode();
}
return Response::HTTP_INTERNAL_SERVER_ERROR;
}
private function isApiPath($request)
{
return false !== strpos($request->getPathInfo(), ApiV3Bundle::API_PREFIX . '/');
}
private function isDebug()
{
return $this->container->get('kernel')->isDebug();
}
}