Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Bugsnag Laravel Laravel Package

bugsnag/bugsnag-laravel

Bugsnag's Laravel and Lumen notifier automatically reports unhandled exceptions and crashes, lets you report handled exceptions via Bugsnag::notify(), and attaches user info and custom diagnostic data to show how many people are affected.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and wire up (5 minutes)

composer require bugsnag/bugsnag-laravel
php artisan vendor:publish --provider="Bugsnag\BugsnagLaravel\BugsnagServiceProvider" --tag=config

Laravel’s package auto-discovery registers the service provider and the Bugsnag facade alias. For Lumen you must wire it manually:

$app->register(Bugsnag\BugsnagLaravel\BugsnagServiceProvider::class);
$app->configure('bugsnag');
class_alias(Bugsnag\BugsnagLaravel\Facades\Bugsnag::class, 'Bugsnag');

Set the key in .env rather than editing config/bugsnag.php:

BUGSNAG_API_KEY=your-key-here
BUGSNAG_RELEASE_STAGE=production

Where to look first

  1. config/bugsnag.php — the only file you’ll routinely touch (api_key, release_stage, notify_release_stages, discard_classes, redacted_keys, max_breadcrumbs, attach_hidden_context).
  2. The Bugsnag facade — the day-to-day surface: notify(), notifyException(), notifyError(), leaveBreadcrumb(), setUser(), and the metadata/feature-flag APIs.
  3. The integration guide for your framework version — the README deliberately defers to docs.bugsnag.com for configuration depth.

First use case: nothing

The most valuable first step is confirming unhandled exceptions already arrive without any code change. Trigger a 500 in a staging environment, verify the report in the dashboard, then check that release_stage shows up correctly. Only after that should you start adding explicit reporting calls.

Second use case: reporting something you caught

try {
    $this->chargeCard($order);
} catch (PaymentGatewayException $e) {
    Bugsnag::notifyException($e, function (Report $report) use ($order) {
        $report->setSeverity('warning');
        $report->addMetadata('order', ['id' => $order->id, 'total' => $order->total]);
    });
    // then handle gracefully — Bugsnag does not swallow the exception
}

Implementation Patterns

Identify the user once, in middleware

The highest-leverage integration is a small middleware that calls Bugsnag::setUser() so every subsequent report (handled or not) carries it:

public function handle($request, Closure $next)
{
    if ($user = $request->user()) {
        Bugsnag::setUser((string) $user->id, $user->email, $user->name);
    }
    return $next($request);
}

Pass primitives (id/email/name), not the Eloquent model. Historic bugs in this package fetched lazy relationships while populating user data (fixed in 2.7.1), and passing scalars keeps payloads small and avoids accidental serialization of sensitive columns.

Breadcrumbs tell the story

Automatic breadcrumbs (queries, logs, events, queue context) cover most cases, but manual crumbs around irreversible or confusing operations are worth the line:

Bugsnag::leaveBreadcrumb('Applying discount', Bugsnag\Breadcrumbs\Breadcrumb::INFO, [
    'code' => $code,
]);

Bound the volume with max_breadcrumbs in config (added in 2.25.0) rather than leaving the default.

Enrich globally with beforeNotify-style callbacks

Instead of repeating metadata at every call site, register a callback once in a service provider:

Bugsnag::registerCallback(function (Report $report) {
    $report->addMetadata('app', [
        'tenant' => tenant()->id ?? null,
        'commit' => config('app.commit'),
    ]);
});

Be careful: global callbacks run for every report including ones already enriched — keep them cheap and idempotent.

Configure discardClasses for known noise

discardClasses (2.22.0) matches exception class names or PHP error names and drops them before sending. This is the correct tool for Symfony\Component\HttpKernel\Exception\NotFoundHttpException, bot-driven InvalidArgumentExceptions, and similar categories that would otherwise burn your event quota. Do it in config, not with if statements scattered across controllers.

Redaction: redactedKeys, not filters

filters is deprecated (2.22.0). redactedKeys supports exact case-insensitive strings and regexes for partial/wildcard matching:

'redacted_keys' => ['password', 'authorization', '/.*_token$/i'],

Note that since 2.20.1 the default filters value is null so Bugsnag PHP’s own defaults apply — don’t “restore” ['password'] and accidentally lose the newer built-in keys.

Logging channel and PSR-3

The package ships a Monolog handler, so you can add a bugsnag channel and Log::channel('bugsnag')->error(...). This is the right integration point for code that already uses a logger rather than the facade. Watch out for multi-logger setups (the duplicate-event bug fixed in 2.15.2) and for logging the same exception both via report() and via the channel.

Queues and commands

Queue context and job info are recorded automatically (2.3.0); console command metadata since 2.9.0. For jobs, use failed() plus Bugsnag::notifyException($e) when you need custom metadata — but remember $this->fail($e) already reports via the exception handler in most setups, so verify you aren’t double-reporting.

Deploy tracking

php artisan bugsnag:deploy --repository=https://github.com/acme/app --revision=$GIT_SHA

Wire this into your deploy pipeline as the last step, otherwise release-stage filtering and regression detection are effectively blind.

Feature flags / experiments

2.24.0 added the feature-flag APIs — call them in your flag-resolution service so reports can be sliced by variant. This is where the package earns its keep over generic error tracking: debugging “broken only for the 10% on the new checkout flow” becomes trivial.

Out-of-memory reporting

Register OomBootstrapper in app/Http/Kernel.php (2.22.0) — it bumps the memory limit by 5 MiB so a fatal OOM can still be serialized and sent.

Gotchas and Tips

  • Missing/invalid API key is silent. Bugsnag generally no-ops rather than throwing. If nothing appears in the dashboard, check BUGSNAG_API_KEY, notify_release_stages, and that release_stage matches what you filtered on — in that order.
  • config:cache traps. Config values read from env() inside a cached config are frozen at build time. Keep all environment variation in .env-driven keys in config/bugsnag.php, and re-run config:cache after changing them.
  • notify() does not rethrow. It reports and returns. For flow control you still need throw or explicit handling — a common source of “we report it but the request succeeds” confusion.
  • Handled vs unhandled is a report property, not a guess. The middleware added in 2.15.0 sets it correctly; if you construct reports manually inside a catch block, don’t expect the framework to mark them unhandled.
  • Lumen sessions. Automatic session capture is disabled for Lumen 5.3+ because session() isn’t available; don’t chase a config flag that won’t help. Attach the relevant state as metadata instead.
  • Breadcrumb leakage across queued jobs. Fixed for Vapor in 2.25.1; on long-running workers (Octane, Horizon) still treat the client as request-scoped and avoid assuming breadcrumbs reset between jobs.
  • Path mapping. If traces show /var/www/... instead of relative paths, use the project_root / strip_path regex options (2.19.0) — this matters for source-map/grouping quality and is the most common “why is grouping weird” cause.
  • attach_hidden_context (2.28.0). Laravel 11’s Context is attached as Laravel Context; hidden context is opt-in. Enabling it can pull in secrets — pair it with redacted_keys before turning it on in production.
  • discardClasses matches class names exactly. No substring matching. Subclass filtering requires listing each class or handling it upstream.
  • Don’t report validation failures. Either add them to Laravel’s $dontReport or to discard_classes. This is the single biggest quota saver in a typical app.
  • Test isolation. For tests, set the client to not notify (or bind a fake) rather than relying on a bogus key; a misconfigured CI environment can otherwise ship test exceptions into production projects.
  • Custom Guzzle. If you need proxy/mTLS/timeouts, bind a bugsnag.guzzle alias in the container (2.21.0) rather than forking the notifier.
  • Version pinning. The package’s Laravel support is version-gated in composer.json; when upgrading Laravel, upgrade this package first — most “it stopped reporting after the framework upgrade” issues are a resolved-version mismatch, not a bug.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin