Originally published byDev.to
How Laravel Handles HTTP Errors
- A request hits a non-existent route
- Router throws NotFoundHttpException
- Exception is caught by Handler
- Laravel looks for resources/views/errors/404.blade.php (example)
- Returns an HTTP 404 response with the rendered view
Common Handling
- app/Exceptions/Handler.php : converts exceptions into HTTP responses.
<?php
namespace App\Exceptions;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Http\Exceptions\ThrottleRequestsException;
use Illuminate\Session\TokenMismatchException;
use Illuminate\Auth\Access\AuthorizationException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;
use Throwable;
class Handler extends ExceptionHandler
{
/**
* The list of the inputs that are never flashed to the session on validation exceptions.
*
* @var array<int, string>
*/
protected $dontFlash = [
'current_password',
'password',
'password_confirmation',
];
/**
* Register the exception handling callbacks for the application.
*/
public function register(): void
{
$this->reportable(function (Throwable $e) {
//
});
// 403 — Forbidden
$this->renderable(function (AuthorizationException $e, $request) {
if (!$request->expectsJson()) {
return response()->view('errors.403', [], 403);
}
});
// 404 — Not Found
$this->renderable(function (NotFoundHttpException $e, $request) {
if (!$request->expectsJson()) {
return response()->view('errors.404', [], 404);
}
});
// 419 — Page Expired (CSRF Token Mismatch)
$this->renderable(function (TokenMismatchException $e, $request) {
if (!$request->expectsJson()) {
return response()->view('errors.419', [], 419);
}
});
// 429 — Too Many Requests
$this->renderable(function (ThrottleRequestsException $e, $request) {
if (!$request->expectsJson()) {
$retryAfter = $e->getHeaders()['Retry-After'] ?? 60;
return response()->view('errors.429', ['retryAfter' => $retryAfter], 429);
}
});
// 503 — Service Unavailable
$this->renderable(function (ServiceUnavailableHttpException $e, $request) {
if (!$request->expectsJson()) {
return response()->view('errors.503', ['exception' => $e], 503);
}
});
}
public function render($request, Throwable $exception)
{
return parent::render($request, $exception);
}
}
- resources/views/errors/{status_code}.blade.php
# example
# resources\views\errors\404.blade.php
@extends('errors.layout')
@section('error_code', '404')
@section('error_content')
<div class="text-center position-relative z-index-1" style="max-width: 520px;">
{{-- Illustration --}}
<div class="mb-6">
<img src="{{ asset('assets/media/illustrations/unitedpalms-1/18.png') }}"
class="error-illustration theme-light-show" alt="404 Not Found" />
<img src="{{ asset('assets/media/illustrations/unitedpalms-1/18-dark.png') }}"
class="error-illustration theme-dark-show" alt="404 Not Found" />
</div>
{{-- Title --}}
<h1 class="fw-bold fs-2x text-gray-900 mb-3">Page Not Found</h1>
{{-- Description --}}
<p class="text-muted fs-5 mb-8 fw-semibold">
Oops! The page you're looking for doesn't exist.<br>
It may have been moved, deleted, or never existed.
</p>
{{-- Actions --}}
<div class="error-actions d-flex gap-3 justify-content-center flex-wrap">
<a href="{{ url()->previous() !== url()->current() ? url()->previous() : '/' }}"
class="btn btn-light btn-lg fw-bold px-8">
<i class="ki-duotone ki-arrow-left fs-2 me-2">
<span class="path1"></span><span class="path2"></span>
</i>
Go Back
</a>
</div>
</div>
@endsection
Then, just create simple routes to test it.
Route::get('/test-404', function () {
abort(404);
});
Also we can customize error pages by creating the views manually or publishing Laravel’s default templates:
php artisan vendor:publish — tag=laravel-errors
Need help building your app? I’m available for freelance web & Android development — raflizocky.netlify.app
☕ Support my writing: paypal.me/raflizocky · saweria.co/raflizocky
🇺🇸
More news from United StatesUnited States
NORTH AMERICA
Related News
How Braze’s CTO is rethinking engineering for the agentic area
10h ago
Amazon Employees Are 'Tokenmaxxing' Due To Pressure To Use AI Tools
21h ago

Implementing Multicloud Data Sharding with Hexagonal Storage Adapters
15h ago

DeepMind’s CEO Says AGI May Be ~4 Years Away. The Last Three Missing Pieces Are Not What Most People Think.
15h ago

CCSnapshot - A Claude Code Configs Transfer Tool
21h ago