kowada-gmbh / error-reporting-bundle
Shared Symfony bundle that automatically e-mails logged errors to a configurable address.
Package info
github.com/Kowada-GmbH/error-reporting-bundle
Type:symfony-bundle
pkg:composer/kowada-gmbh/error-reporting-bundle
Requires
- php: >=8.3
- monolog/monolog: ^3.0
- symfony/config: ^7.4 || ^8.0
- symfony/dependency-injection: ^7.4 || ^8.0
- symfony/http-kernel: ^7.4 || ^8.0
- symfony/mailer: ^7.4 || ^8.0
- symfony/messenger: ^7.4 || ^8.0
- symfony/monolog-bundle: ^4.0
- symfony/twig-bundle: ^7.4 || ^8.0
- symfony/yaml: ^7.4 || ^8.0
Requires (Dev)
- phpstan/extension-installer: ^1.4.3
- phpstan/phpstan: ^2.0
- phpstan/phpstan-symfony: ^2.0
- phpunit/phpunit: ^12.0
- symfony/phpunit-bridge: ^8.1
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Shared Symfony bundle that automatically e-mails logged errors to a configurable address.
The bundle is maintained here as a versioned Composer dependency and pulled into individual Symfony projects via composer update kowada-gmbh/error-reporting-bundle.
Installation
The package is public on Packagist (the source itself stays proprietary, only the distribution is public) and can be required as a regular dependency:
composer require kowada-gmbh/error-reporting-bundle ^1.0
Features
All classes under Kowada\ErrorReportingBundle\ are automatically registered as services via autowiring/autoconfiguration (see config/services.yaml).
Errors that get logged (except HTTP client errors, i.e. any 4xx status) are automatically e-mailed to a configurable address.
Monolog\ErrorHandler: Monolog handler that dispatches errors as anMessage\ErrorMessageover the Messenger bus.MessageHandler\ErrorMessageHandler: sends the e-mail, including the stack trace as an attachment, via@KowadaErrorReporting/emails/error.{html,txt}.twig(needssymfony/twig-bundleactive - without it,TemplatedEmailsilently sends with an empty body instead of failing loudly).
If sending the e-mail itself fails (misconfiguration, mailer outage, unreachable Messenger transport), ErrorHandler catches that instead of letting the exception propagate: the original error is therefore never hidden (it still reaches the other Monolog handlers as usual, e.g. the log file), and the reporting failure is additionally recorded via PHP's error_log(). If an asynchronous Messenger worker ultimately fails to deliver an ErrorMessage (after exhausting retries), this is detected instead of dispatching another ErrorMessage about it — preventing a loop of error reports about failed error reports.
Configuration in the consuming project:
-
Bundle configuration in
config/packages/kowada_error_reporting.yaml:kowada_error_reporting: receiver: 'errors@example.com' sender_address: 'noreply@example.com' sender_name: 'Example Admin' app_name: 'example.com'
If
receiverorsender_addressis missing, the handler throws anUnrecoverableMessageHandlingExceptionon every error. This does not abort the request/command —ErrorHandlercatches it (see above) and writes a notice viaerror_log()instead. Needless to say, you can also use environment variables for configuration instead of baking the values into the app. -
Register the handler in
config/packages/monolog.yaml— recommended in front of Monolog's owndeduplicationhandler, so a recurring error (a cron loop, a broken high-traffic page) doesn't trigger a new e-mail on every single occurrence:monolog: handlers: kowada_error_mail: type: service id: Kowada\ErrorReportingBundle\Monolog\ErrorHandler kowada_error_mail_dedup: type: deduplication handler: kowada_error_mail time: 1800
kowada_error_mail_dedupis the handler actually active in the stack; MonologBundle recognizeskowada_error_mailas referenced by it and does not additionally register it on its own — so nothing needs to be configured twice here.time(in seconds) sets how long an identical error (same level + same message text) is suppressed after the first delivery; the first occurrence of an error is never delayed by this. If plain registration without deduplication is enough, thekowada_error_mailblock alone suffices. -
Recommended: route
ErrorMessageto an asynchronous Messenger transport so sending the e-mail doesn't block the request:framework: messenger: transports: async: '%env(MESSENGER_TRANSPORT_DSN)%' routing: Kowada\ErrorReportingBundle\Message\ErrorMessage: async
Without routing, the e-mail is sent synchronously within the current request.
-
A working
symfony/mailertransport (MAILER_DSN) is assumed.
Development
composer install vendor/bin/phpunit vendor/bin/phpstan analyse