Я использую bugsnag для регистрации ошибок нашего приложения. Приложение построено на Symfony 4, и у меня есть собственный слушатель, который перехватывает исключения и обрабатывает некоторые из них. Что мне нужно, так это сообщить bugsnag, чтобы он игнорировал исключения, которые я обрабатываю вручную (их не нужно регистрировать, поскольку они уже обработаны).
Мой пользовательский прослушиватель имеет более высокий приоритет, чем прослушиватель bugsnag (поэтому он запускается первым). Проблема в том, что остановка распространения событий нарушает другие вещи (например, прослушиватель безопасности больше не запускается, поскольку по умолчанию он имеет более низкий приоритет, чем bugsnag).
Ниже приведен мой код слушателя (ну... соответствующая его часть):
class ExceptionListener
{
protected $router;
private $mailerService;
private $tokenStorage;
private $request;
private $em;
/**
* @var UtilsService
*/
private $utilsService;
public function __construct(Router $router, MailerService $mailerService, TokenStorageInterface $tokenStorage, RequestStack $request, EntityManagerInterface $em, UtilsService $utilsService)
{
$this->router = $router;
$this->mailerService = $mailerService;
$this->tokenStorage = $tokenStorage;
$this->request = $request;
$this->em = $em;
$this->utilsService = $utilsService;
}
public function onKernelException(ExceptionEvent $event)
{
$exception = $event->getException();
$message = $exception->getMessage();
switch (true) {
case $exception instanceof NotFoundHttpException:
// Redirect somewhere
break;
case $exception instanceof CustomException:
// Do some stuff
$event->stopPropagation(); // This does what I need (stops propagation to bugsnag listener) but breaks other things so is not a solution (since it stops propagation to everything).
break;
}
return false;
}
}
Мне нужно просто... в случае, если выброшенное исключение является экземпляром CustomException, я хочу, чтобы оно НЕ было отправлено в bugsnag.
Два возможных решения, которые я вижу (другие приветствуются):
скажите bugsnag, чтобы он каким-то образом игнорировал это исключение: в документации bugsnag я нашел, как это сделать для Laravel (https://docs.bugsnag.com/platforms/php/laravel/configuration-options/ — с помощью dontReport) и Ruby (https://docs.bugsnag.com/platforms/ruby/other/configuration-options/#ignore_classes), но не для Symfony. есть идеи как это сделать?
остановить распространение события только для прослушивателя bugsnag: я не нашел никакой документации по этому поводу. есть идеи как это сделать?
Я думаю, вы могли бы передать EventDispatcher как зависимость и использовать ее для удаления слушателя (или подписчика...), которого вы хотите удалить: EventDispatcher::removeListener(). Хотя я не пробовал.
@ehymel Да, они управляют только необработанными исключениями, но, поскольку дескриптор является слушателем, все они обрабатываются (для них нет блока try catch, обработанный «простой» (не могу найти лучшего слова) не проходит там ).
@jeroen Я действительно зашел на страницу, чтобы добавить тот же самый комментарий, который вы добавили, с той лишь разницей, что кажется, что TraceableEventDispatcher передается функции, а не EventDispatcher.
@jeroen К сожалению, не работает, потому что событие имеет свой собственный стек слушателей после его создания и использует его для вызова следующего слушателя. Удерживается в event->kernel->dispatcher->wrappedListeners. Это свойство защищено (что имеет смысл с архитектурной точки зрения, поскольку обычно слушатель не должен влиять на другого). Взлом этого не кажется мне хорошим решением... но и взлом пакета bugsnag тоже не подходит.






Вы можете реализовать обратный вызов и проверить объект отчета, как описано здесь: https://docs.bugsnag.com/platforms/php/symfony/configuration-options/#обратные вызовы
Просто верните false из обратного вызова, чтобы не сообщать об этом в Bugsnag.
Немного раздражает, что у вас нет доступа к исходному исключению внутри обратного вызова (например, я использую коды ошибок для некоторых проверок, и я не нашел способа получить его, что делает это немного болезненным), но в целом это правильное решение, и оно решило мою проблему. Краткое примечание... термин обратный вызов предполагает что-то, что происходит после того, как запрос выполнен; Я проверил код, и он на самом деле подталкивает к каналу, поэтому «обратный вызов» является скорее промежуточным программным обеспечением (термин фактически помешал мне найти правильный подход в документах, поскольку я полностью пропустил раздел «обратный вызов», думая, что это происходит после запроса) .
Я не использую это, но документы предполагает, что bugsnag управляет только «необработанными» исключениями, и что вы можете довольно легко сообщать об «обработанных» исключениях. Может быть, это сработает?