No description
  • PHP 89%
  • Blade 11%
Find a file
Troy Siedsma c47479c926 README: keep "Is it any good?", drop redundant canonical-repository line
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 15:58:51 +00:00
config Modernize for Laravel 11/12 ->withExceptions() wire-in 2026-05-22 15:55:55 +00:00
resources/views/email Modernize for Laravel 11/12 ->withExceptions() wire-in 2026-05-22 15:55:55 +00:00
src Modernize for Laravel 11/12 ->withExceptions() wire-in 2026-05-22 15:55:55 +00:00
.gitattributes Re-platform onto LithiumHosting/laravel-exception-mailer Forgejo origin 2026-05-22 13:14:19 +00:00
.gitignore Re-platform onto LithiumHosting/laravel-exception-mailer Forgejo origin 2026-05-22 13:14:19 +00:00
composer.json Modernize for Laravel 11/12 ->withExceptions() wire-in 2026-05-22 15:55:55 +00:00
LICENSE.md Standardize composer.json + README + LICENSE 2026-05-22 15:03:46 +00:00
README.md README: keep "Is it any good?", drop redundant canonical-repository line 2026-05-22 15:58:51 +00:00

Laravel Exception Mailer

Mail every uncaught Laravel exception to a configured operator list. Useful as a low-noise companion to Sentry or as a no-frills alerting channel on small apps that don't justify a full APM. Tested on Laravel 11 and 12.

Installation

composer require lithiumhosting/laravel-exception-mailer

Publish the config (and optionally the email template) when you want to customize defaults:

php artisan vendor:publish --tag=laravel-exception-mailer-config
php artisan vendor:publish --tag=laravel-exception-mailer-views

Wire it into your app

Laravel 11 and 12 no longer ship App\Exceptions\Handler. Register the reporter inside bootstrap/app.php:

use Illuminate\Foundation\Configuration\Exceptions;
use LithiumHosting\ExceptionMailer\Reporters\ExceptionReporter;

return Application::configure(basePath: dirname(__DIR__))
    // ...
    ->withExceptions(function (Exceptions $exceptions) {
        $exceptions->report(ExceptionReporter::class);
    })->create();

That's the entire wire-up. The reporter is resolved out of the container on each invocation, so the underlying ExceptionMailer service is constructed lazily.

Configuration

config/laravel-exception-mailer.php (after publishing):

Key Default What it does
subject Laravel Exception Subject-line prefix prepended to every alert.
notify_emails [mail.from] List of recipients. Strings or ['address' => ..., 'name' => ...] entries.
notify_environment ['production', 'staging'] Environments that actually send mail. Other environments are silent.
ignore_exceptions Auth / validation / 404 / 405 Exception classes (or parents) that don't generate mail. Matched with instanceof.
queue_mail true Send via the queue instead of blocking the response.
queue_connection / queue_name null Override the connection/queue the mailable is dispatched on.

Environment overrides:

EXCEPTION_MAILER_SUBJECT="Uh oh, LiBilling"
EXCEPTION_MAILER_QUEUE=true
EXCEPTION_MAILER_QUEUE_CONNECTION=redis
EXCEPTION_MAILER_QUEUE_NAME=alerts

What ends up in the email

The mail uses Laravel's Markdown mail components, so it inherits your app's branded mail theme. Each report carries:

  • Exception class, message, file and line
  • Full stack trace
  • For HTTP requests: method, URL, route name, IP, user agent, session id, pretty-printed query / post / headers
  • For console invocations: working directory and argv

Sensitive headers (cookies, authorization) are passed through as-is from the request, exactly the same data Laravel's exception handler hands to your logger. Don't enable this in environments where the operator inbox isn't trusted with that material.

License

This package, laravel-exception-mailer is licensed under The MIT License (MIT). Please see License File for more information.

Is it any good?

Yes.

When people first hear about a new product, they frequently ask if it is any good. A Hacker News user remarked:

Note to self: Starting immediately, all raganwald projects will have a "Is it any good?" section in the readme, and the answer shall be "yes.".