Your Guide to Laravel Excellence

Better Error Handling with onFailure Callback in Laravel's DB::transaction() (New in Laravel 12.9)

Better Error Handling with onFailure Callback in Laravel's DB::transaction() (New in Laravel 12.9)

In Laravel 12.9, the DB::transaction() method was improved to allow an onFailureCallback, which is a function that gets called if the transaction fails (throws an exception or error).

Before this update:

If something failed during a DB::transaction(), you could catch it outside manually, but it wasn't built-in cleanly.

Now:

  • Laravel lets you pass a second parameter, onFailureCallback, inside the DB::transaction() itself.

  • This makes handling failures more elegant and localized.

  • It keeps your code cleaner and centralized around the transaction logic.

DB::transaction(
    function () use ($id) {
        $articleImage = ArticleImages::findOrFail($id);
        $articleImage->delete();
    },
    onFailureCallback: function (Throwable $e) use ($user, $id) {
        $articleImage = ArticleImages::find($id); // It might have been deleted or not
        Notification::send($user, new ImageDeletionFailedNotification($articleImage, $e->getMessage()));
    }
);

✅ **Main Transaction: Try to find and delete an image.

If it fails:

Maybe image is already deleted, or some DB error happens.

The onFailureCallback sends a notification to the user telling them the deletion failed, along with the error message.

Real Life Examples:

  1. Order Processing System

Suppose you are processing an e-commerce order:

DB::transaction(
    function () use ($order) {
        $order->markAsPaid();
        $order->reduceStockLevels();
    },
    onFailureCallback: function (Throwable $e) use ($user, $order) {
        Notification::send($user, new OrderProcessingFailedNotification($order, $e->getMessage()));
    }
);

If marking as paid or reducing stock fails, the customer is notified that the order couldn't be processed.

  1. Blog Publishing Workflow

If either saving post or notifying subscribers fails, the error is logged for investigation.

DB::transaction(
    function () use ($postData) {
        $post = Post::create($postData);
        Notification::send(User::subscribers(), new NewPostNotification($post));
    },
    onFailureCallback: function (Throwable $e) {
        Log::error('Blog publishing failed: '.$e->getMessage());
    }
);

Publishing a blog creates the blog post and notifies all subscribers:

Recommeded Posts

Per-Second Rate Limiting in Laravel 11

Per-Second Rate Limiting in Laravel 11

Per-Second Rate Limiting in Laravel 11

2 months ago Read article →
How to Add Real-Time Comments in Laravel 11 with Laravel Reverb

How to Add Real-Time Comments in Laravel 11 with Laravel Reverb

How to Add Real-Time Comments in Laravel 11 with Laravel Reverb

2 months ago Read article →
How to Prevent Spam in Laravel Forms with spatie/laravel-honeypot

How to Prevent Spam in Laravel Forms with spatie/laravel-honeypot

How to Prevent Spam in Laravel Forms with spatie/laravel-honeypot

2 months ago Read article →
Guide to Session Management and Flash Messages in Laravel

Guide to Session Management and Flash Messages in Laravel

Learn how to use Laravel's session management and flash messages. This comprehensive guide covers storing data, handling user states, and displaying temporary notifications in your Laravel applications.

2 months ago Read article →