
How to Handle Job Failures in Laravel 12 with FailOnException
Streamline your job exception logic with Laravel's
FailOnException
middleware – no more boilerplatetry/catch
blocks!
Introduction
In Laravel 12, handling job exceptions is cleaner than ever thanks to the FailOnException
middleware. Previously, you'd often write verbose try/catch
blocks inside your queued job's handle()
method.
Now, with FailOnException
, you can move exception handling out of the method and into middleware — resulting in more maintainable and readable code.
The Traditional Way (Verbose)
Here’s the older approach many Laravel developers use:
public function handle(TranslateContent $action): void
{
try {
$action->handle($this->content);
} catch (Throwable $exception) {
if ($exception instanceof InvalidContentFormatException) {
$this->fail($exception);
return;
}
throw $exception;
}
}
Problems with the Traditional Approach
- Repetitive boilerplate across jobs.
- Obscures the business logic (main
handle()
intent). - Easy to forget to rethrow exceptions or call
$this->fail()
properly.
The Laravel 12 Way (Elegant)
Here’s the cleaner version using FailOnException
:
public function handle(TranslateContent $action): void
{
$action->handle($this->content);
}
Then define the middleware:
public function middleware(): array
{
return [
new FailOnException([InvalidContentFormatException::class]),
];
}
Final Example Class
<?php
use DateTime;
use Throwable;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Foundation\Queue\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\Middleware\FailOnException;
class ProcessContentTranslation implements ShouldQueue
{
use Dispatchable, Queueable;
public function __construct(private readonly Content $content) {}
public function handle(TranslateContent $action): void
{
$action->handle($this->content);
}
public function retryUntil(): DateTime
{
return now()->addHours(5);
}
public function middleware(): array
{
return [
new FailOnException([InvalidContentFormatException::class]),
];
}
}