graham-campbell/exceptions
Graham Campbell's Exceptions package gives Laravel apps a cleaner, more powerful exception handling setup, with custom handlers, reporting, throttling, and rendering so errors are easier to manage and debug.
Architecture fit: Graham Campbell Exceptions is a drop-in replacement for Laravel’s default exception handler and centralizes exception-to-response mapping, custom HTML/JSON renderers, and per-exception log levels. Conceptually it fits Laravel well because every app already has an exception-handling seam. As a TPM, treat it as Tier-0 infrastructure on the global error path, not as a feature library. It can be leveraged as a platform-hygiene enabler for consistent API error contracts, safer production responses, and centralized reporting, but it does not create user-facing capability.
Integration feasibility: Mechanically low effort: Composer install, service-provider/config publication, handler binding, and configuration of mappings. The real effort is not wiring; it is defining and owning the error taxonomy, response envelope, status-code mapping, and reporting behavior. A proof-of-value spike on one route plus one JSON/API path is enough to validate fit before broad rollout.
Technical risk: The dominant risk is dependency governance. The package has weak adoption signals: 0 dependents, a low package score, and effectively a single-maintainer surface owning a privileged place in the request lifecycle. The failure mode is not immediate breakage; it is abandonment or incompatibility two Laravel majors from now while the package owns your error path. There is also coupling risk with Laravel 11’s native bootstrap/app.php / withExceptions() configuration, and operational risk if renderers perform I/O during degraded-system conditions.
TPM leverage: Use the package to support a retain-and-upgrade or build-vs-buy decision: it can reduce custom exception-handler code, standardize API/web error behavior, and support Laravel 11 / PHP 8.4 upgrade readiness via v17.2.0. Do not position it as strategic differentiation. Gate adoption on a short spike, documented error taxonomy, golden-file behavior tests, and a written exit plan.
Key questions:
withExceptions() configuration, and which surface wins when both are configured?Stack fit: Laravel 10–11 on PHP 8.2–8.4, with ^17.2 required for explicit Laravel 11 and PHP 8.4 support. Best fit is a Laravel application that wants declarative exception-to-response mapping instead of scattered try/catch, custom render() overrides, and inconsistent abort() usage. It is a poor fit if Laravel’s default handler is sufficient or if the team cannot absorb another dependency.
Migration path: Treat this as an error-contract migration, not a Composer task.
render() overrides, custom abort codes, validation/404/429/auth responses, API envelopes, and reporting paths.Compatibility checks: Validate Laravel 11 slim skeleton behavior, config caching, queue/failed_jobs reporting, Sanctum/Passport unauthenticated responses, Octane/worker reuse if applicable, and the interaction between published package config and bootstrap/app.php exception configuration. Confirm that composer.json constraints and transitive dependencies are compatible with the target PHP/Laravel baseline.
Sequencing: Prefer doing this before or alongside a Laravel 11 / PHP 8.4 upgrade so error-path behavior is observable during the framework major. If the framework upgrade is already in flight, defer this to the following release; bundling both changes makes regression attribution impossible. Use the package as a modernization enabler, but keep it out of user-facing roadmap commitments.
Maintenance: Low steady-state code maintenance, but meaningful governance maintenance. Every new exception class, API error-contract change, and Laravel major adds a review step. Assign a named owner for the error contract and mapping table. Keep custom handlers thin and few; sprawl makes the exit plan expensive.
Support: This is the dominant operational exposure because of low adoption and maintainer concentration. Mitigations: pin the exact version, commit composer.lock, keep the wrapper thin, document the error-code reference, and pre-agree a revert to Laravel’s native handler plus a small in-house render() override. Do not require broad community support or commercial backing for this package to be acceptable; instead require an explicit fallback and owner.
Scaling: Throughput cost is negligible under normal load. The scaling concern is failure scaling: error paths receive burst traffic precisely when the system is degraded. Enforce pure mapping renderers with no I/O. Resolve user context, request IDs, and correlation data at throw time or from in-memory data only. Ensure reporting is not duplicated between Laravel’s reporter and the package.
Failure modes to plan for:
Ramp-up: Low for Laravel-fluent engineers; moderate for support, QA, client teams, and on-call. Publish a one-page error-code and status-mapping reference in release notes before rollout. The document, not just the code, is the operational deliverable.
TPM posture: Green-light only as platform hygiene with a named owner, golden-file coverage of current error behavior, a documented error taxonomy, and a written fallback to Laravel’s native handler. If any of those are missing, defer. The package is optional; owning the error path is not.
How can I help you explore Laravel packages today?