src/EventSubscriber/ExceptionListener.php line 63

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace Slivki\EventSubscriber;
  4. use Psr\Log\LoggerInterface;
  5. use Slivki\Controller\Admin\BePaid\ValidateBePaidCredentialsAction;
  6. use Slivki\Controller\Api\GiftSubscription\CancelSubscriptionAction;
  7. use Slivki\Controller\Api\OnlineOrder\Vendor\GetNearestTimeAction;
  8. use Slivki\Controller\Api\Profile\Balance\BalanceTransferAction;
  9. use Slivki\Controller\Api\Profile\VirtualWallet\TransferSlivkiPayBalanceAction;
  10. use Slivki\Controller\MobileApi\V2\GiftCertificate\RefundGiftCertificateAction;
  11. use Slivki\Controller\Payment\Click\CompletePaymentAction;
  12. use Slivki\Controller\Payment\Click\PreparePaymentAction;
  13. use Slivki\Controller\Payment\Oplati\GetStatusOplatiTransactionAction;
  14. use Slivki\Controller\Subscription\GetChildSubscribersAction;
  15. use Slivki\Controller\Subscription\ShareSubscriptionAction;
  16. use Symfony\Component\HttpFoundation\JsonResponse;
  17. use Symfony\Component\HttpFoundation\Response;
  18. use Symfony\Component\HttpKernel\Event\ExceptionEvent;
  19. use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
  20. use Symfony\Component\Messenger\Exception\HandlerFailedException;
  21. use Throwable;
  22. use function json_decode;
  23. use function array_filter;
  24. use function count;
  25. use function json_last_error;
  26. final class ExceptionListener
  27. {
  28.     private const API_NAMESPACES_START = [
  29.         'Api\V2',
  30.         'UserController::loginAction',
  31.         'Api\Partner',
  32.         'Api\Coupon',
  33.         'Api\Scheduler',
  34.         'Admin\Api',
  35.         'OnlineOrder\GiftCertificate\EditGiftCertificateOnlineOrderAction',
  36.         'MobileApi\Partner',
  37.         'Api\OnlineOrder\Payment\Method',
  38.         ValidateBePaidCredentialsAction::class,
  39.         GetNearestTimeAction::class,
  40.         ShareSubscriptionAction::class,
  41.         GetChildSubscribersAction::class,
  42.         PreparePaymentAction::class,
  43.         CompletePaymentAction::class,
  44.         GetStatusOplatiTransactionAction::class,
  45.         CancelSubscriptionAction::class,
  46.         BalanceTransferAction::class,
  47.         TransferSlivkiPayBalanceAction::class,
  48.         RefundGiftCertificateAction::class,
  49.     ];
  50.     private LoggerInterface $logger;
  51.     public function __construct(LoggerInterface $logger)
  52.     {
  53.         $this->logger $logger;
  54.     }
  55.     public function onKernelException(ExceptionEvent $event): void
  56.     {
  57.         $exception $this->getException($event->getThrowable());
  58.         $exceptionMessage $exception->getMessage();
  59.         $controller $event->getRequest()->attributes->get('_controller');
  60.         if (null !== $controller && $this->isIncludedToRoute($controller)) {
  61.             json_decode($exceptionMessagetrue);
  62.             $isJson json_last_error() === JSON_ERROR_NONE;
  63.             $this->logger->error(
  64.                 'Exception occurred in controller',
  65.                 [
  66.                     'exception' => $exception,
  67.                     'isJson' => $isJson,
  68.                     'controller' => $controller,
  69.                 ]
  70.             );
  71.             $response = new JsonResponse(
  72.                 $isJson $exceptionMessage : ['error' => $exceptionMessage],
  73.                 $exception->getCode() !== $exception->getCode() : Response::HTTP_INTERNAL_SERVER_ERROR,
  74.                 [],
  75.                 $isJson
  76.             );
  77.             if ($exception instanceof HttpExceptionInterface) {
  78.                 $response->setStatusCode($exception->getStatusCode());
  79.                 $response->headers->replace($exception->getHeaders());
  80.             }
  81.             $event->setResponse($response);
  82.         }
  83.     }
  84.     private function isIncludedToRoute(string $controller): bool
  85.     {
  86.         $matches array_filter(
  87.             self::API_NAMESPACES_START,
  88.             static fn(string $needle): bool => strpos($controller$needle) !== false,
  89.         );
  90.         return count($matches) > 0;
  91.     }
  92.     private function getException(Throwable $exception): Throwable
  93.     {
  94.         return $exception instanceof HandlerFailedException
  95.             $this->getException($exception->getPrevious())
  96.             : $exception;
  97.     }
  98. }