laravel-rescue-replace-try-catch-fallback-tip.png
Шаблон кодуLaravel

Laravel rescue(): Controlled Fallback Without a Large try/catch

Use rescue() for fallback values, automatic exception reporting, conditional report callbacks, and concise handling of optional operations without a large try/catch block.

Sometimes an exception should not stop the entire request. An optional service may fail while the page can still render its primary data.

When a try/catch exists only to return a fallback value and optionally report the exception, Laravel provides the concise rescue() helper.

Replace a Large try/catch Used Only for Fallback

До
php
try {    $data = $service->load();} catch (Throwable $exception) {    report($exception);     $data = null;}
Після
php
$data = rescue(    fn () => $service->load(),    rescue: null,    report: true,);

rescue() executes the callback. On success, its result is returned. If a throwable occurs, Laravel may send it through the normal exception reporting path and return the configured fallback value.

The intent is direct: try to load the data, and return null if that operation fails.

With named arguments, the second parameter is named rescue, not default. The correct form is rescue: null.

Without a Second Argument, the Fallback Is Already null

PHP - null is the default fallback
$profile = rescue(    fn () => $profileService->load($userId),);

If the callback succeeds, $profile contains its return value. If a throwable occurs, rescue() returns null by default.

Exception reporting is also enabled by default.

The Fallback Can Be More Than null

PHP - Use an empty array as fallback
$settings = rescue(    fn () => $settingsService->load($userId),    rescue: [],    report: true,);

Choose a fallback that keeps the code after rescue() predictable. If the successful result is an array, returning [] may be clearer than switching to an unrelated type.

The Fallback Can Be Calculated by a Callback

PHP - A fallback callback receives the throwable
$rates = rescue(    fn () => $ratesService->loadCurrent(),    rescue: fn (Throwable $exception) =>        $cache->get('rates:last-known', []),    report: true,);

The second argument may be a callback. Laravel passes the caught Throwable to it, so fallback logic can inspect the failure or simply return a last-known value from cache.

This is useful when the fallback is not a single constant but still remains a small and understandable operation.

report: true Keeps the Failure Visible

PHP - Return a fallback and report the failure
$preview = rescue(    fn () => $previewService->build($document),    rescue: null,    report: true,);

A fallback does not mean the failure should disappear. With report: true, the throwable is sent through Laravel's normal exception handler while the current request continues with the fallback result.

This is one of the strongest uses of rescue(): the user flow can continue while the technical problem stays visible to monitoring and logs.

Use report: false Only for Truly Expected Failures

PHP - Intentionally suppress reporting for an expected failure
$value = rescue(    fn () => $optionalService->load(),    rescue: null,    report: false,);
Do not set report: false just to make logs quieter. If the exception represents a real failure, the fallback may protect the user flow while the exception should still remain visible.

Reporting Can Be Decided Per Throwable

PHP - Conditional reporting with a callback
$value = rescue(    fn () => $service->load(),    rescue: null,    report: fn (Throwable $exception): bool =>        $exception instanceof RuntimeException,);

The report argument may be a callback instead of a boolean. It receives the throwable and returns a boolean, allowing reporting only for selected failures.

rescue() Catches Throwable, Not Only Exception

The current Laravel implementation catches Throwable, which is broader than a normal Exception.

That is why the scope around rescue() should stay narrow. Wrapping a large block can accidentally turn a serious programming failure into an ordinary null.

Wrap Only the Operation Where Fallback Is Acceptable

До
php
$result = rescue(function () use ($order) {    $this->validateOrder($order);    $this->chargeCustomer($order);    $this->reserveStock($order);    $this->sendAnalytics($order);     return $order;}, rescue: null);
Після
php
$order = $checkoutService->complete($order); $analytics = rescue(    fn () => $analyticsService->send($order),    rescue: null,    report: true,);

A critical business workflow should not silently collapse into a fallback. If charging a customer or reserving stock fails, the application normally needs explicit handling or the exception should propagate.

Optional analytics after the main operation succeeds can be a better candidate for rescue() when its failure must not break the user response.

rescue() Does Not Retry the Operation

PHP - Use retry() for repeated attempts
$result = retry(    3,    fn () => $remoteService->load(),    200,);

rescue() and retry() solve different problems. rescue() runs the callback once and provides a controlled result after failure. retry() is designed to attempt the operation again.

They may be combined when retrying is genuinely appropriate for that operation.

When Plain try/catch Is Still Better

  • when different exception types require different actions;
  • when recovery requires several steps;
  • when resource cleanup or a finally block is needed;
  • when the failure is an important part of the business workflow rather than just a reason to return a fallback;
  • when an explicit try/catch communicates complex behavior more clearly.

A good rescue() call does not hide failure. It defines a clear boundary: this specific operation may fail, this is the safe fallback result, and this is the rule for whether the throwable should be reported.

#laravel-12 #laravel-13 #php-8-4 #php-8-5 #rescue #fallback #error-handling #exception-reporting

Схожі поради

laravel-throw-if-throw-unless-guard-clauses-tip.pngПорада
Переглянути пораду
#laravel-12 #laravel-13 #php-8-4 #php-8-5 #error-handling #throw-if #throw-unless #guard-clauses
laravel-withwherehas-avoid-duplicate-conditions-tip.pngПорада
Переглянути пораду
#eloquent #laravel-12 #laravel-13 #php-8-4 #php-8-5 #where-has #with-where-has #eager-loading #relationships
laravel-tap-side-effects-keep-original-value-tip.pngПорада
Переглянути пораду
#eloquent #laravel-12 #laravel-13 #php-8-4 #php-8-5 #tap #helpers #tappable
laravel-firstorcreate-replace-first-create-tip.pngПорада
Переглянути пораду
#eloquent #laravel-12 #laravel-13 #php-8-4 #php-8-5 #model-persistence #first-or-create #first-or-new