6

I use bugsnag to log errors for our app. The app is built over symfony 4 and I have a custom listener that catches exceptions and treats some of them. What I need is to tell bugsnag to ignore the exceptions that I manually handle (there is no need for them to be logged since they are already treated).

My custom listener has higher priority than bugsnag listener (so is ran first). The problem is that stopping event propagation breaks other stuff (for example security listener is not run any more since it has lower priority than bugsnag by default).

Below is my listener code (well... relevant part of it):

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;
}
}

What I need is simple... in case the exception thrown is an instance of CustomException I want it NOT to be sent to bugsnag.

The 2 possible solutions that I see are (others are welcomed ofc):

zozo
  • 8,230
  • 19
  • 79
  • 134
  • I don't use this, but the [docs](https://docs.bugsnag.com/platforms/php/symfony/#reporting-handled-exceptions) suggests that bugsnag only manageas "unhandled" exceptions, and that you can report "handled" exceptions pretty easily. Maybe that will work? – ehymel Jun 14 '19 at 14:52
  • 1
    I guess you could pass the EventDispatcher as a dependency and use that to remove the listener (or subscriber...) you want to remove: `EventDispatcher::removeListener()`. I haven't tried it though. – jeroen Jun 14 '19 at 14:57
  • @ehymel Yes, they only manage unhandled exceptions, but since the handle is a listener all of them are treated (no try catch block for those, the "simple" (can't find a better word) handled don't pass through there). – zozo Jun 14 '19 at 15:06
  • @jeroen I actually entered the page to put the exact same comment you added, with the only difference that it seems TraceableEventDispatcher is passed to the function not EventDispatcher. – zozo Jun 14 '19 at 15:06
  • @jeroen Unfortunately doesn't work because the event has its own stack of listeners once it's been created and is using that one for calling next listener. Is hold under event->kernel->dispatcher->wrappedListeners. That property is protected (which makes sens from an arhitectural point of view since normally a listener should't affect another). Hacking into that doesn't seem like a good solution to me... but neither does hacking into bugsnag bundle. – zozo Jun 14 '19 at 15:58

1 Answers1

3

You can implement a callback and inspect the report object as described here: https://docs.bugsnag.com/platforms/php/symfony/configuration-options/#callbacks

Simply return false from the callback to prevent reporting to Bugsnag.

Bugsnag Support
  • 381
  • 1
  • 4
  • 1
    Is a bit annoying that you don't have access to the original exception inside the callback (for example I use error codes for some checks and I found no way to get it, making this a bit of a pain) but overall this is the right solution and it solved my problem. Quick note... the term callback suggests something that happens after the request is done; I checked code and it actually pushes to pipe so the "callback" is more of a middleware (the term actually prevented me to find the right approach in docs, since I totally skipped the "callback" section thinking that it happens after the request). – zozo Jun 18 '19 at 09:49