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

Php Airbrake Bundle Laravel Package

ibrows/php-airbrake-bundle

A Symfony bundle that integrates the Airbrake PHP client, helping you send application exceptions and errors to Airbrake for monitoring, tracking, and reporting.

View on GitHub
Deep Wiki
Context7

Getting Started

Confirm what you're actually holding. This is a Symfony 2.3–2.8 era bundle, not a Laravel package. There is no service provider, no config/ publish, no Facade. As a Laravel developer your realistic relationship with it is one of three: (a) you've inherited a legacy Symfony app and must keep its Airbrake pipeline alive, (b) you're evaluating it and should immediately substitute airbrake/phpbrake behind a small Laravel provider, or (c) you're reading it to understand the "config + listener" shape before writing your own 40-line integration. Set expectations accordingly — the reusable asset is the ibrows/php-airbrake notifier underneath, not the bundle.

Install and prove it boots before reading any code.

composer require ibrows/php-airbrake-bundle
php bin/console list   # container compiles?

If the container fails to compile, stop — check the composer.json PHP and symfony/symfony constraints against your runtime. The listener calls ExceptionEvent::getException(), which was removed in Symfony 4.x; on modern Symfony it will fatal the first time an exception fires. That is your compatibility gate, and it is binary.

Register the bundle (Symfony 2/3 style — no Flex auto-registration):

// app/AppKernel.php
$bundles = [
    // ...
    new Ibrows\PhpAirbrakeBundle\IbrowsPhpAirbrakeBundle(),
];

Configure it, then verify the wiring:

# app/config/config.yml
ibrows_php_airbrake:
    api_key:     "%airbrake_api_key%"
    project_id:  "%airbrake_project_id%"
    environment: "%kernel.environment%"
    host:        api.airbrake.io
    secure:      true
php bin/console debug:container | grep -i airbrake
php bin/console debug:event-dispatcher kernel.exception

Where to look first, in order. These three files are the entire product:

  1. DependencyInjection/Configuration.php — the authoritative config schema. Every key you're guessing at lives here.
  2. DependencyInjection/IbrowsPhpAirbrakeExtension.php — tells you the exact service IDs registered. They shift between versions (ibrows_php_airbrake vs ibrows.php_airbrake vs ibrows.php_airbrake.client), so read, don't assume.
  3. EventListener/ExceptionListener.php — this is the integration. Everything else is plumbing around it.

First use case — automatic exception capture. Throw from a controller in prod, load the page, check the Airbrake dashboard. If the notice doesn't appear, the cause is almost always environment-name filtering or an api_key/project_id mismatch — not the wiring. Verify the notifier works standalone with a scripted $client->notify(...) before blaming the bundle.

If you're on Laravel, skip the bundle entirely. composer require airbrake/phpbrake, bind it in a provider, and hook App\Exceptions\Handler::report() (or withExceptions() on Laravel 11+). Copy the shape of this bundle — singleton notifier + one exception hook — not the code.

Implementation Patterns

Automatic capture is the default and needs zero code. The listener subscribes to kernel.exception and reports the thrown exception. For the vast majority of legacy Symfony apps that is the entire integration. Do not write a second listener to duplicate it; you'll double-report.

Manual reporting in rescue blocks — inject the notifier, not the bundle. When you want to record an error and keep executing, inject the client service:

use Airbrake\Client;

public function __construct(Client $airbrake)
{
    $this->airbrake = $airbrake;
}

public function syncAction(): Response
{
    try {
        $this->doRiskySync();
    } catch (\Throwable $e) {
        // Report but continue — e.g. show a partial-success page.
        $this->airbrake->notify($e);
        return $this->renderPartialSuccess($e);
    }
    return $this->renderSuccess();
}

This is the highest-value day-to-day pattern: report, don't rethrow, when the operation is recoverable.

Enrich the context yourself — the bundle won't. The legacy listener reports the exception and whatever the notifier captures by default. That is rarely enough to triage. Where you control the call site, attach:

$this->airbrake->notify($e, [
    'context' => [
        'user_id'     => $this->getUser()?->getId(),
        'route'       => $request->attributes->get('_route'),
        'environment' => $this->getParameter('kernel.environment'),
        'release'     => $this->getParameter('app.release_sha'),
        'request_id'  => $request->headers->get('X-Request-Id'),
    ],
]);

Without this, your dashboard shows stack traces with no way to answer "who, where, which deploy."

Filter before it leaves the process. The legacy notifier will happily ship request params, headers, and cookies. Add a scrubbing step at the call site — strip Authorization, Cookie, X-CSRF-TOKEN, session IDs, and query-string secrets before handing the exception to notify(). If you use the automatic listener for most errors, that means writing your own kernel.exception listener (at a higher priority) that wraps the client with request sanitization — the built-in listener gives you no hook for this.

Guard the reporter against its own failures. The notifier is a synchronous HTTP call. Wrap it:

try {
    $this->airbrake->notify($e);
} catch (\Throwable $reportingFailure) {
    $this->logger->error('Airbrake notify failed', ['ex' => $reportingFailure]);
    // Never let a reporting failure propagate into application code.
}

Error reporting must be observationally pure from the application's perspective.

Use the framework reporter for non-exception errors. The bundle captures exceptions. PHP warnings, caught-and-logged failures, and business-rule violations never reach it. Pair it with a Monolog handler at error level so your Airbrake stream reflects actual error volume, not just the subset that got thrown.

When evaluating: read it as a template, then substitute. If Airbrake is mandated but the bundle is incompatible, the two-day migration is: bind airbrake/phpbrake as a singleton, route exceptions through Laravel's report() or Symfony's newer exception event, add the context and scrubbing shown above, keep a Monolog handler alongside. You replace three files with three files and inherit a maintained dependency.

If legacy code references bundle service IDs, ship a thin adapter class preserving the old interface for one release cycle, then delete it. Don't let a dead bundle's names leak into new code.

Gotchas and Tips

The exception-listener API is the hard compatibility wall. getException() on ExceptionEvent was deprecated in Symfony 4.4 and removed in 5.x. If your exception listener is not being invoked at all on 4.4+, this is why — you need getThrowable(). Do not assume "it compiles" means "it reports"; test an actual thrown exception in prod.

Zero stars / zero dependents is a risk statement, not a footnote. Assume you are the only team running this in production anywhere. That means: no Stack Overflow corpus, no peer to ask, no one to file a CVE against. If you keep it, fork it into your own namespace, pin the version, assign an owner, and write a removal date. Budget 1–2 days per quarter to track framework and PHP upgrades.

Silent ingestion failure after API-key rotation or endpoint deprecation is the failure mode to design against. The legacy notifier can fail without throwing. Add a canary: notify a health-check endpoint on boot in staging, alert if Airbrake receives zero notices in a window, and log every notify() outcome. If you can't tell whether errors are reaching Airbrake, you don't have monitoring — you have a false sense of it.

The synchronous notifier sits on the request path. In an outage, error volume spikes exactly when your app can least afford a per-request curl round-trip. Set a hard client timeout (the notifier's default is generous), and consider pushing notifications to a queue. Never let a slow reporter turn a page error into a page timeout.

Environment filtering is your friend — and your first-place-to-look bug. environment: "%kernel.environment%" combined with any server-side env filter can silently drop everything from dev (good) or from prod (very much not). If production notices aren't landing, log the resolved environment value inside the listener before the notify call.

Config keys are versioned and inconsistent. The Configuration.php in your installed version is the only source of truth. api_key vs project_key, presence of project_id, and service-ID naming all drift between releases. Read the file; don't trust blog posts or this assessment's examples for keys you haven't verified.

PII leakage is real. Legacy notifier defaults capture request parameters and headers, unfiltered. If you're handling anything regulated, scrub before sending — session IDs, auth headers, form bodies, IP addresses if your policy requires it. This is a compliance item, not a cleanliness preference.

Extension points are thin — use them, don't fight them. The bundle's only real hooks are the config schema and the event listener. If you need custom context, filtering, or async dispatch, you're writing your own listener that wraps the client. That's fine — but recognize it means you've outgrown the bundle, and the maintained notifier will serve you better than a fork of the wrapper.

When in doubt, replace. Airbrake's own maintained Symfony bundle, sentry/sentry-symfony, or airbrake/phpbrake behind a provider all deliver the same outcome with versioned releases, security posture, and an issue tracker. The bundle's only defensible niche is a timeboxed stabilization of an old app with an existing Airbrake contract and no roadmap for a framework upgrade. Treat it as a reversible stopgap, not a foundation.

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.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core