Get "PHP 8 in a Nuthshell" (Now comes with PHP 8.3)
Amit Merchant

Amit Merchant

A blog on PHP, JavaScript, and more

Cleaner exception handling using rescue() helper in Laravel

If you want to make your web application robust, you get to handle those quirky and unpredictable exceptions. And the way you do that in PHP is by using try-catch blocks in your code. The same applies in the case of Laravel as well.

The traditional way

So, for instance, if you want to handle the exception when something goes wrong when saving/updating the model record, you can handle exceptions like so.

public function store(Request $request)
{  
    try   
    {  
        $comment = new BlogComment();  
        $comment->content = $request['comment'];  
        $comment->user_id = Auth::user()->id;  
        $comment->blog_id = $request['ticketId'];  
        $comment->save(); 
    } catch(Exception $e) { 
        if (!($e instanceof SQLException)) {
            app()->make(\App\Exceptions\Handler::class)->report($e); 
            // Report the exception if you don't know what actually caused it
        }
        request()->session()->flash('unsuccessMessage', 'Failed to add comment.');  
        return redirect()->back();
    }
}

As you can tell, we’re using Laravel’s in-built error handling in the catch block to report the exception if it occurs.

Now, this is perfectly fine but do you know there’s a slicker and a cleaner way in Laravel that you can use to make this even shorter. Enter the rescue() helper.

The rescue() helper

Laravel provided this rescue() helper in which you can pass in the piece of code as a closure for which you want to handle exceptions. The helper will execute the given closure and catches any exceptions that occur during its execution. All exceptions that are caught will be sent to the exception handler.

So, if we want to rewrite the previous example using the rescue() helper, we can do it like so.

public function store(Request $request)
{
    rescue(function () use ($request) {
        $comment = new BlogComment();  
        $comment->content = $request['comment'];  
        $comment->user_id = Auth::user()->id;  
        $comment->blog_id = $request['ticketId'];  
        $comment->save();
    }, function() {
        request()->session()->flash('unsuccessMessage', 'Failed to add comment.');  
        return redirect()->back();
    }, true);
}

As you can tell, the rescue() helper can accept three arguments.

  • The first argument as I discussed is the closure that holds the code that you want exception handled.
  • The second argument (optional) is the closure that will get run if an exception occurs or you can also pass in the default value here which will be returned when an exception occurs.
  • The third argument (optional) accepts a boolean value which will determine if you want to report the exception or not.
    • If it’s true, the rescue() helper will report the exception to the configured error handler.
    • If it’s false, the rescue() helper won’t report the exception.

Pretty neat, right?

If you’re curious, here’s how the function definition of rescue() helper looks like.

/**
 * Catch a potential exception and return a default value.
 *
 * @param  callable  $callback
 * @param  mixed  $rescue
 * @param  bool  $report
 * @return mixed
 */
function rescue(callable $callback, $rescue = null, $report = true)
{
    try {
        return $callback();
    } catch (Throwable $e) {
        if ($report) {
            report($e);
        }

        return $rescue instanceof Closure ? $rescue($e) : $rescue;
    }
}
Learn the fundamentals of PHP 8 (including 8.1, 8.2, and 8.3), the latest version of PHP, and how to use it today with my new book PHP 8 in a Nutshell. It's a no-fluff and easy-to-digest guide to the latest features and nitty-gritty details of PHP 8. So, if you're looking for a quick and easy way to PHP 8, this is the book for you.

Like this article? Consider leaving a

Tip

👋 Hi there! I'm Amit. I write articles about all things web development. You can become a sponsor on my blog to help me continue my writing journey and get your brand in front of thousands of eyes.

Comments?