DEV Community

david duymelinck
david duymelinck

Posted on

1

Laravel rescue helper

I just saw a rescue helper article, and I'm wondering what was the mindset when this code was written?

if (! function_exists('rescue')) {
    /**
     * Catch a potential exception and return a default value.
     *
     * @template TValue
     * @template TFallback
     *
     * @param  callable(): TValue  $callback
     * @param  (callable(\Throwable): TFallback)|TFallback  $rescue
     * @param  bool|callable(\Throwable): bool  $report
     * @return TValue|TFallback
     */
    function rescue(callable $callback, $rescue = null, $report = true)
    {
        try {
            return $callback();
        } catch (Throwable $e) {
            if (value($report, $e)) {
                report($e);
            }

            return value($rescue, $e);
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

If I would see code like

    public function fetchAccountData($accountId)
    {
        return rescue(function () use ($accountId) {
            $response = Http::timeout(3)->get("api.external.com/accounts/{$accountId}");
            return $response->json();
        }, [
            'id' => $accountId,
            'name' => 'Unknown',
            'status' => 'error',
            'last_checked' => now()
        ]);
    }
Enter fullscreen mode Exit fullscreen mode

My mind would explode. What are we rescuing?
Now I seen the rescue code, it rescues return $response->json();

The rescue helper is misusing the not capturing catches feature from PHP 8.0.
In the RFC you see it should be used when the exception is defined and will never need debugging.
By setting the catch to Throwable you don't know which part of the function returned the exception because you don't know which exception is thrown.
That is why added the report argument. Which triggers another weird function.

if (! function_exists('report')) {
    /**
     * Report an exception.
     *
     * @param  \Throwable|string  $exception
     * @return void
     */
    function report($exception)
    {
        if (is_string($exception)) {
            $exception = new Exception($exception);
        }

        app(ExceptionHandler::class)->report($exception);
    }
}
Enter fullscreen mode Exit fullscreen mode

I took a dive in the code and it logs the exception if the Throwable isn't a part of the not reportable exceptions.
So they created a whole system to lose information about what is going on with the code.

Real problems could occur if rescue is used for code that opens a file or a database connection. This is where the finally block shines.

Please use try catch blocks with all the nuances it provides instead of the rescue function. Someone will thank you later.

Top comments (0)

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay