M19.4 §6 (#96): branded, guest-safe error pages (404/500/503/429 + 403)#100
Conversation
Only errors/403 existed, and it rendered inside <x-app-layout> (assumes an authenticated user). Error pages get served to logged-out visitors, so: - New <x-error-layout>: guest-safe, self-contained, dependency-free (renders with no auth context or built assets — important for 500/503), on-brand. Recovery link adapts: dashboard when authed, home/login for guests. - Branded 404, 500, 503, 429 views (Laravel auto-renders; JSON handled by the framework). 500 shows a friendly message only — never debug detail (APP_DEBUG=false posture). 503 reads as maintenance with auth-free recovery. - Migrated errors/403 onto the guest-safe layout; kept its $details passthrough and existing copy (4 tests pin that wording). - tests/Feature/CustomErrorPagesTest: real 404 path, 500 no-debug-leak, 503 maintenance/auth-free, 429, 403 details, auth-vs-guest recovery, guest-safe render of every view. 419 stays out — handled by the M19.2 auth redirect, not an error page. Full suite: 373 passed. Fixes #96 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5b5e705846
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| @isset($actions) | ||
| {{ $actions }} | ||
| @else | ||
| @auth |
There was a problem hiding this comment.
Avoid auth lookups while rendering error pages
When this layout is used for the 500 page, @auth calls the session guard's check(); for a request that carries an auth session but hits a database outage or another failure before the user has been loaded, that check can try to hydrate the user and throw while the error page is rendering. This reintroduces an auth/database dependency into the supposedly self-contained error page, so logged-in users may get a fallback exception response instead of the branded 500. Prefer a non-loading check or always guest-safe links in the shared error layout.
Useful? React with 👍 / 👎.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
What
Closes the gap from #96: only
errors/403.blade.phpwas customized, and it rendered inside<x-app-layout>(which assumes a logged-in user). Every other HTTP error fell through to Laravel's generic, unbranded page.Changes
<x-error-layout>— a guest-safe, self-contained, dependency-free layout (renders with no auth context and no built assets, so it holds up for 500/503), styled on-brand (navy/orange, CZ mark, dark-mode aware). Recovery link adapts: dashboard when authenticated, home/login for guests.errors/{code}; JSON requests are handled by the framework.APP_DEBUG=false).<x-app-layout>onto the guest-safe layout; kept its$detailspassthrough and the existing "Sorry, you don't have permission." copy (4 tests pin it).CustomErrorPagesTest— real 404 path, 500 no-debug-leak under production posture, 503 maintenance/auth-free, 429, 403 details, auth-vs-guest recovery, and guest-safe render of every view.Out of scope: 419 — handled by the M19.2 auth-hardening redirect, not an error page (no 419 view).
Full local suite: 373 passed. Live 404 confirmed branded.
Fixes #96
🤖 Generated with Claude Code