Files
kupshop/bundles/KupShop/ContentBundle/EventSubscriber/ExceptionSubscriber.php
2025-08-02 16:30:27 +02:00

73 lines
2.2 KiB
PHP

<?php
declare(strict_types=1);
namespace KupShop\ContentBundle\EventSubscriber;
use Doctrine\DBAL\Exception\DeadlockException;
use Doctrine\DBAL\Exception\LockWaitTimeoutException;
use KupShop\KupShopBundle\Util\Logging\SentryLogger;
use Symfony\Component\ErrorHandler\Error\OutOfMemoryError;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Contracts\Service\Attribute\Required;
class ExceptionSubscriber implements EventSubscriberInterface
{
#[Required]
public SentryLogger $sentryLogger;
public static function getSubscribedEvents(): array
{
return [
KernelEvents::EXCEPTION => [
['registerLog', 200],
],
];
}
public function registerLog(ExceptionEvent $event): void
{
$exception = $event->getThrowable();
$loopLimit = 0;
while ($exception !== null) {
if ($exception instanceof DeadlockException) {
$this->loggingWithProcessList($exception, '!!! DEADLOCK !!!');
return;
}
if ($exception instanceof LockWaitTimeoutException) {
$this->loggingWithProcessList($exception, '!!! LOCK TIMEOUT !!!');
return;
}
// Protože hrozí, že při dalším zpracování dojde paměť exception handleru,
// radši zkusím hned takhle co nejdřív poslat do Sentry, ať o tyhle hnusný chyby nepříjdeme.
if ($exception instanceof OutOfMemoryError) {
increaseMemoryLimit(100);
\Sentry\captureException($exception);
return;
}
$exception = $exception->getPrevious();
$loopLimit++;
if ($loopLimit >= 5) {
break;
}
}
}
private function loggingWithProcessList(\Throwable $e, string $title): void
{
$this->sentryLogger->captureException(
new \Exception($title, $e->getCode(), $e), [
'extra' => json_encode(sqlQuery('SHOW FULL PROCESSLIST')->fetchAllAssociative()),
]);
}
}