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

Airbrake Bundle Laravel Package

i22/airbrake-bundle

Symfony bundle that integrates Airbrake error monitoring, automatically capturing exceptions and reporting them to your Airbrake project. Provides simple configuration and service integration for tracking production errors in Symfony applications.

View on GitHub
Deep Wiki
Context7

Getting Started

First thing to internalize: this is a Symfony bundle, not a Laravel package. There is no composer require i22/airbrake-bundle in your future — the bundle's value-add is Symfony-specific (a Bundle subclass, a DI Extension/Configuration tree, compiler passes). Laravel has no equivalent surface for any of that. So "getting started" here means reading it as a reference implementation, not installing it.

Read these files in the repo, in order:

  1. composer.json — the require block tells you the Symfony/PHP version window the author targeted. Expect Symfony 2.x/3.x-era constraints and an old PHP floor. This is the fastest way to confirm it won't co-install with a modern Laravel app.
  2. DependencyInjection/Configuration.php — this is the spec. It enumerates every config knob the author thought was worth exposing (project ID, API key, environment, ignore/exclude lists, filters). Treat it as your requirements doc for the Laravel port.
  3. DependencyInjection/*Extension.php — shows how the notifier is constructed and what it's wired to (client service, event subscriber, or a Monolog handler).
  4. The reporter/handler/subscriber class — this is the ~150 lines you actually care about. It's the adapter between "an exception happened" and "a payload goes to Airbrake."

First use case, end to end, in a Laravel app:

composer require airbrake/phpbrake   # the plain notifier the bundle wraps
php artisan vendor:publish --tag=...
// app/Providers/AirbrakeServiceProvider.php
public function register(): void
{
    $this->app->singleton(\Airbrake\Notifier::class, fn () => new \Airbrake\Notifier([
        'projectId' => config('services.airbrake.project_id'),
        'projectKey' => config('services.airbrake.project_key'),
        'environment' => app()->environment(),
        'host' => config('services.airbrake.host', 'https://api.airbrake.io'),
        // filters mirror the bundle's Configuration.php ignore rules
        'filter' => [app(AirbrakeFilter::class), 'filter'],
    ]));
}

Then two wiring points — and only two:

// bootstrap/app.php  (Laravel 11)
->withExceptions(function (Exceptions $exceptions) {
    $exceptions->report(function (Throwable $e) {
        try {
            app(\Airbrake\Notifier::class)->notify($e, [
                'user_id' => auth()->id(),
                'release' => config('app.version'),
            ]);
        } catch (\Throwable) { /* fail open, always */ }
    });
});

That's the minimum viable port. Throw a synthetic exception in tinker, confirm it lands in the Airbrake dashboard with the right environment tag, and you've matched the bundle's functionality.

Implementation Patterns

Pattern 1 — Singleton notifier behind a contract. Don't let Airbrake\Notifier leak into app code. Bind an App\Contracts\ErrorReporter interface (single notify(Throwable $e, array $context = []) method) to an AirbrakeReporter. This is the whole point of the vendor-portability decision: swapping to Sentry later is one binding, not a grep-and-replace across the codebase. The bundle's own coupling surface, per the assessment notes, is roughly one handler plus config — replicate exactly that, no more.

Pattern 2 — Funnel everything through the exception handler. Uncaught exceptions are the 80% case. Handler::report() (or the withExceptions closure above) is your single choke point. Resist the urge to scatter $reporter->notify() calls through controllers; you'll end up with duplicates and gaps.

Pattern 3 — Monolog handler for explicitly-logged errors. The bundle, being Symfony, typically also wires a Monolog handler so logger->error() reaches Airbrake. In Laravel, register a custom channel or a tap on the default stack:

// In a service provider boot():
Log::listen(function ($message) use ($reporter) {
    if (in_array($message->level, ['error', 'critical', 'alert', 'emergency'], true)
        && $message->context['exception'] ?? null) {
        $reporter->notify($message->context['exception']);
    }
});

Be careful not to double-report: if you both tap the logger and use withExceptions, a logged exception that also bubbles can ship twice. Cheap dedupe: hash class + file + line + environment in a short cache.

Pattern 4 — Queue failures are separate. Handler::report() does not see failed jobs. Wire them explicitly in AppServiceProvider::boot():

Queue::failing(fn (JobFailed $event) => app(ErrorReporter::class)
    ->notify($event->exception, ['job' => $event->job->resolveName()]));

The bundle doesn't have a queue concept at all — this is Laravel-side value-add the source won't give you.

Pattern 5 — Enrich context, then scrub it. The bundle advertises "context-rich notifications"; replicate by attaching a request-scoped context array (user ID, route, release SHA, request ID). Then, before send, pass it through a filter that strips Authorization, Cookie, password, password_confirmation, _token, card_number, and anything matching a PII regex. Author this list as code and write a test that posts a realistic request body containing an auth header and a password and asserts neither appears in the outgoing payload.

Pattern 6 — Get the HTTP call out of the request path. The notifier is synchronous by default. Wrap the notify call in a queued job dispatched on terminate(), or at minimum configure an aggressive sub-second connect timeout. Under PHP-FPM, a slow Airbrake endpoint becomes tail latency, and tail latency becomes workers exhausted.

Pattern 7 — Sampling and rate limiting, configured not coded. Airbrake's ingest supports sampling/de-duplication server-side. Set it up before production. A single noisy exception in a loop can burn a month's quota in minutes, and when quota is gone reporting is silent — you lose visibility precisely during the incident you needed it for. The bundle's config schema will likely list an ignore/exclude array; port that literally, plus a hard client-side counter as a backstop.

Pattern 8 — Release tagging for deploy correlation. config('app.version') fed into the notifier's release field lets you correlate a spike to a deploy. This is the feature that makes error tracking useful rather than just present, and it's a one-line addition — don't skip it in the POC.

Gotchas and Tips

The install won't work, and that's the first thing you'll discover. Composer will refuse the bundle against Laravel 10/11 because it pins old symfony/* components that conflict with the Symfony packages Laravel already ships. Don't burn an afternoon on --ignore-platform-reqs; the result wouldn't run anyway. Read the source, port the handler.

Guzzle major-version hell. phpbrake depends on Guzzle. Check it against AWS SDK, Stripe, social auth, and anything else in the estate before committing — Guzzle 6/7 splits are the most common dependency conflict in Laravel projects. If you need Guzzle 7 and the notifier wants 6, that's a fork-or-pick-another-vendor moment.

Recursive failure is real. A notifier that throws inside the exception handler produces blank 500s or a loop. Every reporting call, without exception, goes in a try { } catch (\Throwable) { }. Fail open, always.

Silent drop is the failure mode nobody notices. Airbrake unreachable, key rotated, quota exhausted — in all three cases your app keeps serving 200s and the dashboard keeps looking quiet. Add a scheduled synthetic exception (an Artisan command that throws a tagged HealthCheckException on a schedule) and alert if it stops arriving.

The project key is write-only, but it still belongs in env/secret storage, and it differs per environment. Separate projects (or at minimum separate environment tags) for staging and production, or your signal gets drowned by test traffic. Rotating the key without updating every service silently zeros reporting — make key rotation a checklist item, not a manual step.

Monolog 2 vs 3 will bite you if you write a custom handler. HandlerInterface signatures changed; the bundle predates Monolog 3 entirely. If you copy a handler class out of the source, check the interface against your installed Monolog major before assuming it compiles.

Where to debug when errors "aren't showing up." In order: (a) is the env var populated at runtime — php artisan tinker and echo it, don't trust the .env file; (b) does a direct notify() from tinker arrive — if yes, the wiring is wrong, if no it's credentials/network; (c) can the container actually reach api.airbrake.io — outbound firewalls and proxies are a frequent culprit on internal services; (d) is your filter/scrubber accidentally returning an empty payload — filters that mutate can silently null out the report.

Extension points you probably want that the bundle won't teach you: job-failure reporting, request-ID correlation, user-context attachment, and the ErrorReporter abstraction itself. Everything the bundle gives you is the minimum; the Laravel-side polish is your work.

Maintenance posture: vendor the code, don't depend on the package. Zero stars and zero dependents means any bug you find, you fix, and no one else has hit it first. The recommended play is to treat the bundle as ~150 lines of audited reference code copied into your own small App\Support\Airbrake package that you control. Budget a couple hours a quarter for notifier drift.

If Airbrake isn't already a contracted vendor, stop here. Do the half-day bake-off against sentry/sentry-laravel first. It's first-party, one-command install, actively maintained, and you'd spend less total time than reading this bundle — and the vendor decision outlives whichever adapter you write.

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.
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment