naiskit/laravel-oops
Laravel Oops is a lightweight package for cleaner error handling in Laravel apps. It helps replace raw exceptions with friendly, customizable error pages and clearer responses, making failures easier to understand for users and developers. Simple to install and configure without disrupting your work...
Architecture fit. The package is a drop-in Laravel exception renderer: a service provider plus a page composer (Naiskit\LaravelOops\Rendering\ErrorPageComposer) that intercepts the framework's error rendering pipeline. It has no database, queue, cache, or middleware dependency of its own, so coupling is low and it fits standard Laravel 11–13 monoliths and API apps equally. The v2 design is effectively a small design system: theme (one Blade view = layout/visuals) × tone (lang file = copy voice) × lang (en/id), with per-app overrides resolved through Laravel's standard resources/views/vendor/oops/ and lang/vendor/oops/ namespacing. That is a clean, conventional extension seam a TPM can plan around without forking the package.
Integration feasibility. High for a greenfield install; moderate for existing v1 users. The breaking surface is broad but mostly config-shaped: five env vars remain, copy moves to publishable lang files (--tag=oops-lang), and a large set of v1 knobs is deleted. Because Laravel returns null for unknown config keys, removed options will fail silently to defaults rather than throw — meaning a v1 app can upgrade "successfully" and ship visual/localization regressions that no test catches unless someone looks at the rendered pages.
Technical risk. Several items warrant verification before we commit:
.env settings and "all other options are gone," yet the same document describes config('oops.theme') with light/dark forcing, color/accent overrides, logo images, icon_align, background_image, mascot, and show_footer. They list OOPS_FORCE, OOPS_SHOW_FOOTER, OOPS_BACKGROUND_IMAGE, and light/dark mode as removed, then re-describe each as added or configurable. They list insight, support copy, the footer, and back-to-back quote suppression as both removed and added. This reads like an unreconciled merge of two changelogs. Treat the tag's actual source and README as the source of truth and re-run this assessment against them.SECURITY.md plus tests/Feature/SecurityTest.php asserting that exception messages, stack traces, and file paths never reach the page — including under APP_DEBUG=true with forced rendering — addresses the single worst failure mode of error-page packages. Note the contradiction that this test references oops.force, a key listed as removed.OOPS_LANG no longer follows app.locale and only ships en/id. Apps serving other locales will now render English error pages to non-English users unless we author tone/lang files.Key questions.
OOPS_FORCE/oops.force, show_footer, light/dark, and the quote system present or gone?Stack fit. Confirmed support matrix: PHP 8.2 / 8.3 / 8.4 × Laravel 11 / 12 / 13, validated in CI alongside PHPStan/Larastan level 5 and coverage reporting. This matches our runtime targets; the constraint is that apps still on PHP 8.1 cannot adopt v2.
Pre-flight audit (do this before touching the dependency). Grep the codebase and infra for every removed key and artifact: OOPS_FORCE, oops.statuses, oops.view, oops.messages, oops.default_message, oops.ui, oops.quotes_path, OOPS_QUOTE_GENRES, all OOPS_THEME_*/OOPS_COLOR_*/OOPS_LOGO_*, OOPS_ICON_ALIGN, OOPS_BACKGROUND_IMAGE, OOPS_SHOW_FOOTER; plus usages of the oops:quote command, the QuoteRepository contract, and --tag=oops-quotes. Anything found is either deleted or re-expressed in the new theme/tone/lang model.
Migration path.
composer update, and immediately clear/publish: --tag=oops-lang if we override copy, and custom themes into resources/views/vendor/oops/themes/.formal); language → a {lang} lang directory; footer → the toggle.OOPS_LANG in .env for any app not serving en — do not rely on app.locale.config:cache) in every environment; env-only changes are invisible until then.Compatibility notes. Published v1 views will not match the v2 theme structure — they must be rewritten, not carried over. Any dashboards or runbooks referencing quote genres, oops:quote, or the session "no repeat" quote tracking are obsolete; quote behavior is now either fixed per-status (wise tone) or gone. Custom log/alerting that keyed off OOPS_FORCE needs a replacement trigger.
Sequencing. Treat as a contained, single-PR change per app: audit → upgrade on a branch → visual diff of all six status pages (light and, if applicable, dark/OS-preferred) → staging soak with APP_DEBUG both true and false to validate the security guarantee → production rollout behind the normal release train. No cross-team coordination required; the package owns no data or interfaces of its own.
Maintenance. Ongoing surface drops sharply: five env vars and no per-status views, quote library, or color/logo matrices to keep in sync. Dependabot (composer + GitHub Actions, weekly) and a CONTRIBUTING.md reduce the cost of tracking upstream. The trade is less runtime tunability — anything we previously tweaked via config now requires a published theme or tone file, which is versioned in our repo and therefore more durable, but also our problem to maintain across future majors.
Support. The reference code is the most operationally valuable addition: every rendered page carries a short code (e.g. OOPS-500-A82F) that is logged alongside the real exception class, message, and stack trace — error for 5xx, warning for everything else. That gives the service desk a deterministic join key between a customer screenshot and our logs. It requires a runbook ("ask for the code, search the log stream, escalate with the stack trace") and a log-access/retention policy review, since stack traces and exception messages are now systematically captured on user-visible paths. The technical tone also gives internal/IT audiences actionable guidance without a separate page.
Scaling. Per-render cost is a Blade render plus one log write — negligible even under incident-scale 5xx storms. The real scaling consideration is log volume: logging every 4xx at warning with a stack trace can materially inflate ingest during bot traffic, 404 crawls, or 419/429 bursts. Set retention and, if needed, sampling or a level override before enabling broadly on high-traffic public apps.
Failure modes to design around.
config:cache into deploy.en/id audiences get English copy — a visible regression for international products.Ramp-up. Low. A mid-level Laravel developer can complete the upgrade and author a custom theme or tone in well under a day. The cost concentrates in the audit and in visual QA across statuses, not in learning the package — provided the maintainer's documentation matches what actually shipped, which, given the state of these notes, is the first thing to confirm.
How can I help you explore Laravel packages today?