Your Guide to Laravel Excellence

How to Handle Job Failures in Laravel 12 with FailOnException

How to Handle Job Failures in Laravel 12 with FailOnException

Streamline your job exception logic with Laravel's FailOnException middleware – no more boilerplate try/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]),
        ];
    }
}

Recommeded Posts

Laravel Localization: How to create a Multilingual Website in Laravel

Laravel Localization: How to create a Multilingual Website in Laravel

Laravel Localization: How to create a Multilingual Website in Laravel

3 months ago Read article →
CRUD with Alpine.js, Tailwind CSS, and jQuery DataTable Modals

CRUD with Alpine.js, Tailwind CSS, and jQuery DataTable Modals

Learn how to build a full CRUD system using Alpine.js, Tailwind CSS, and jQuery DataTable, complete with modals for better user experience.

3 months ago Read article →
How to Accept Credit Card Payments in Laravel 12 Using Square

How to Accept Credit Card Payments in Laravel 12 Using Square

Learn how to easily add Square credit card payments to your Laravel 12 website. Step-by-step guide for secure and smooth payment integration.

2 months ago Read article →
Resize Images using intervention-image

Resize Images using intervention-image

Resize Images using intervention-image

3 months ago Read article →