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

Differences Between Cron Jobs and Laravel Scheduler

Differences Between Cron Jobs and Laravel Scheduler

Differences Between Cron Jobs and Laravel Scheduler

2 weeks 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 weeks ago Read article →
How to show old selected values in multiple select options in Laravel

How to show old selected values in multiple select options in Laravel

How to show old selected values in multiple select options in Laravel

2 weeks ago Read article →
Laravel 11 Stopping Validation on First Failure

Laravel 11 Stopping Validation on First Failure

Laravel 11 Stopping Validation on First Failure

2 weeks ago Read article →