Error Pages
Last updated: 04/17/2026 · Written by Agent0
Error Pages
StackCTL includes styled error pages for the most common HTTP error codes. They're fully standalone — no layout dependency — so they render correctly even if the framework itself has encountered a problem. In local development, they show detailed debug information to help you diagnose issues fast.
Error Page Files
Error pages live in resources/views/errors/:
resources/views/errors/ ├── 403.php ← Access Denied ├── 404.php ← Page Not Found └── 500.php ← Application Error
Triggering Error Pages
Use the abort() helper anywhere in a controller or middleware to stop execution and render the appropriate error page.
abort(404); // Page Not Found abort(403); // Access Denied abort(500); // Application Error
Some errors are triggered automatically by the framework:
- 404 — Fired automatically when no route matches the incoming request
- 403 — Fired by
role:andcan:middleware when a permission check fails - 419 — Fired automatically when a POST request has a missing or invalid CSRF token. Falls back to the 500 page if no 419 view exists.
- 500 — Rendered when an unhandled exception reaches the top level
Local vs. Production Behavior
Error pages check config('app.env') to decide how much information to show.
In local development (env = 'local')
- 500 — Shows the full exception message, the file and line number where the error occurred, and a complete stack trace
- 403 — Shows an optional debug reason string if one was passed to
abort()
In production (env = 'production')
- All debug output is hidden
- Users see only the friendly error message and navigation buttons
- No internal file paths, exception details, or stack traces are ever exposed
This is handled automatically — just make sure config('app.env') is set to 'production' before going live.
Customizing Error Pages
The error page files are plain PHP/HTML — edit them freely to match your app's branding. A few things worth keeping in mind:
- Error pages are standalone — they include their own
<html>,<head>, and Tailwind CDN load. They intentionally do not use a layout, because the layout itself might be the source of the error. - The app logo is pulled from
config('app.logo.main'), so updating your logo inconfig/app.phpwill reflect on all error pages automatically. - Keep the debug blocks wrapped in
if (config('app.env') === 'local')so they never appear in production.
Example: Adding a custom message to the 404 page
<!-- In resources/views/errors/404.php -->
<p class="text-gray-600 dark:text-gray-300 mb-6">
The page you're looking for doesn't exist or has been moved.
If you need help, <a href="/contact" class="underline">contact us</a>.
</p>
Adding a Custom Error Code
If you need an error page for a code not currently covered — for example a 419 CSRF page — create a new file in resources/views/errors/ named after the code. The abort() helper will pick it up automatically, falling back to 500.php if the file doesn't exist.
// Create: resources/views/errors/419.php // abort(419) will now render it automatically