bugsnag / bugsnag-symfony

BugSnag notifier for the Symfony PHP framework. Monitor and report errors in your Symfony apps.
https://docs.bugsnag.com/platforms/php/symfony
MIT License
43 stars 21 forks source link

Symfony Console support #160

Open danepowell opened 1 year ago

danepowell commented 1 year ago

Description

I maintain Acquia CLI, a Symfony Console application. I can't figure out how to report exceptions to Bugsnag via this library.

Many libraries similar to Bugsnag, such as Amplitude, support a singleton pattern of interaction, i.e. Bugsnag::getInstance()->notifyException(new Exception()) as opposed to $this->get('bugsnag')->notifyException(new Exception()).

The singleton pattern is a lot easier (possibly, the only way) to integrate with Symfony Console applications, which are really stripped down from a full Symfony app. For instance, I don't even know what $this or get() referenced above are supposed to refer to. In a console app, assuming you are throwing an exception from a Command (usually the case), $this would be an instance of \Symfony\Component\Console\Command\Command and it would have no such method get(). I assume this is something to do with the service container or framework bundle, which generally shouldn't / can't be accessed directly in CLI apps.

We also throw a custom AcquiaCliException and we'd really love to report to bugsnag from within that exception. Since it extends \Exception, it has no access to Symfony resources. +1 to using the singleton pattern here.

Finally, I'm not sure if Console apps support bundles, I suspect not, which means that autoreporting uncaught exceptions won't work either.

Describe the solution you'd like

Guidance on how to integrate with Console apps, via a singleton pattern or some other method.

johnkiely1 commented 1 year ago

Hi @danepowell

You should be able to get Bugsnag in your console application by leveraging Symfony dependency injection mechanism. https://symfony.com/doc/current/console.html#getting-services-from-the-service-container

bugsnag-symfony registers the @bugsnag service so in your services.yaml file, you should bind the Bugsnag instance to your service parameters by:

services:
    # resolve "Bugsnag\Client" to the Bugsnag service
    Bugsnag\Client: '@bugsnag

Any parameter with the type Bugsnag\Client will get the Bugsnag service.

So this means you can then inject it as below into your classes and use it like any other property.

private $bugsnag;

public function __construct(\Bugsnag\Client $bugsnag)
{
    $this->bugsnag = $bugsnag;
}

Hope that helps.

danepowell commented 1 year ago

Thanks, but the main problem is that our app eschews the FrameworkBundle for performance reasons, and this means we cannot natively load bundled packages (including Bugsnag).

Is there a way to access the Bugsnag classes (especially the event listeners) without using bundles?

For instance, adding something like this to my app's services.yml:

services:
  Bugsnag\Client: ~
  Bugsnag\Configuration: ~
  Bugsnag\BugsnagBundle\EventListener\BugsnagListener: ~
  Bugsnag\BugsnagBundle\EventListener\BugsnagShutdown: ~

The problem so far is that the Bugsnag classes don't seem to support autowiring, so I would need to wire all of the Bugsnag classess myself.

danepowell commented 1 year ago

I think I'll go with a simpler PHP integration for now, without using the bugsnag-symfony package: https://github.com/acquia/cli/pull/1240

I'm still interested to know if there's a way to use all of the nice bugsnag-symfony event listeners without using the bundle directly.

johnkiely1 commented 1 year ago

Hi @danepowell,

I think the best workaround at present would indeed be, like you suggested, to wire the classes yourself. To that end we have now added an item on the roadmap to try and address this within our library. I will let you know of updates on this thread as soon as I have any.