
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:
- 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.
- 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: