Laravel Error Handling: Custom Exceptions
Laravel Error Handling: Custom Exceptions
Laravel Error Handling: Custom Exceptions
Tip: Custom Exception with Render
class PaymentFailed extends Exception
{
public function render(Request $request): Response
{
return response()->json(['error' => 'Payment failed'], 402);
}
}
Gotcha: Exception Handler Priority
$this->reportable(function (PaymentFailed $e) {
// Custom reporting
});
Register reportable and renderable callbacks in App\Exceptions\Handler.
Tip: Report vs Render
report() logs the exception. render() returns an HTTP response. They're separate concerns.
Gotcha: Don't Report Expected Errors
protected $dontReport = [
PaymentFailed::class,
];
Tip: Exception Context
public function report(): void
{
Log::error('Payment failed', [
'order_id' => $this->order->id,
'amount' => $this->order->total,
]);
}
Gotcha: API vs Web Error Responses
Check expectsJson() to return different formats.
Tip: Use route:cache Carefully
php artisan route:cache is fast, but it doesn't work with closure-based routes. Every time you cache routes, Laravel serializes them. If you have Route::redirect() or closure callbacks, the cache breaks. Stick to controller-based routes in production.
Tip: Model APP_KEY Rotation
Rotating APP_KEY invalidates all encrypted data — cookies, encrypted DB columns, and password reset tokens. If you must rotate (e.g., after a leak), plan a migration that re-encrypts existing data with the new key.
Gotcha: Local Scope Leaks
Global scopes defined in booted() apply to ALL queries on that model — including relationships. An innocent User::all() in admin panel might exclude soft-deleted users if a global scope is active.
Senior Insight
Custom exception handling is where Laravel apps reveal their maturity level. The default exception handler is fine for prototypes, but production apps need granular rendering per exception type. I organize exceptions into categories — client errors (4xx), server errors (5xx), and third-party failures (timeouts, rate limits) — with distinct rendering and logging for each. And always report exceptions you don't handle; silent failures are the hardest to debug.
Source: Laravel News (https://laravel-news.com/), Freek.dev (https://freek.dev/tags/laravel), Spatie Blog (https://spatie.be/blog)