0

Hàm rescue() trong Laravel là gì? Vũ khí tối thượng để xử lý ngoại lệ gọn gàng

Khi viết code Laravel, chúng ta thường xuyên phải đối mặt với các đoạn code có nguy cơ bắn ra Exception (lỗi ngoại lệ), ví dụ như gọi API bên thứ ba, đọc file, truy vấn dữ liệu nhạy cảm hoặc tính toán phức tạp.

Cách thông thường để xử lý là bọc chúng trong khối try-catch truyền thống:

use Illuminate\Support\Facades\Log;

try {
    $result = $service->callExternalApi();
} catch (\Exception $e) {
    Log::error($e->getMessage());
    $result = null; // hoặc một giá trị mặc định nào đó
}

Đoạn code trên không sai, nhưng nó làm phình to Controller hoặc Service của bạn bằng những dòng boilerplate code lặp đi lặp lại.

Đó chính là lý do Laravel cung cấp hàm helper toàn cục rescue() — một giải pháp cực kỳ thanh lịch để thay thế khối try-catch trong các tình huống an toàn.


1. Hàm rescue() là gì?

rescue() là một helper function được dựng sẵn trong Laravel, cho phép bạn thực thi một đoạn code có rủi ro sinh ra lỗi, tự động bắt lỗi đó (catch), ghi log (hoặc không), và trả về một giá trị mặc định hoặc chạy một closure dự phòng nếu có sự cố xảy ra mà không làm sập ứng dụng.

Cú pháp cơ bản:

$result = rescue(function () {
    // Đoạn code dễ sinh ra exception
    return $service->callExternalApi();
}, $fallbackValue);

2. Các tác dụng và cách sử dụng thực tế

A. Trả về giá trị mặc định khi xảy ra lỗi

Thay vì dùng try-catch dài dòng để gán giá trị fallback, bạn chỉ cần truyền giá trị đó vào tham số thứ hai của rescue():

// Nếu đọc file config hoặc tính toán bị lỗi, hệ thống tự động trả về 0 thay vì sập
$stock = rescue(function () {
    return $inventoryService->getStockCount($productId);
}, 0);

B. Sử dụng Closure (Hàm ẩn danh) cho giá trị fallback phức tạp

Nếu giá trị fallback cần một đoạn logic tính toán nặng hoặc gọi một service dự phòng khác, bạn có thể truyền một Closure vào tham số thứ hai:

$user = rescue(function () {
    return Http::timeout(2)->get('https://api.external.com/user/' . $id)->json();
}, function () use ($id) {
    // Fallback: Lấy dữ liệu tạm từ cache cục bộ khi API bên ngoài tạch
    return Cache::get('fallback_user_' . $id);
});

C. Tắt tính năng ghi Log (Report Error)

Mặc định, khi rescue() bắt được một ngoại lệ, nó sẽ tự động ghi log ngoại lệ đó thông qua Laravel Log hệ thống.

Tuy nhiên, nếu đó là một lỗi nằm trong dự liệu (ví dụ: parse một chuỗi JSON không hợp lệ từ dữ liệu rác của user) và bạn không muốn làm ô nhiễm file log, bạn có thể truyền thêm tham số report: false:

$data = rescue(function () {
    return json_decode($untrustedString, true, 512, JSON_THROW_ON_ERROR);
}, [], report: false);

3. Khi nào nên dùng rescue() và khi nào KHÔNG NÊN dùng?

✅ Nên dùng khi:

  • Thực hiện các tác vụ không mang tính chất sống còn (non-critical tasks) đối với luồng chính của request, ví dụ: gọi dịch vụ thống kê, bắn sự kiện log phụ, gọi API bên thứ ba dự phòng, gửi thông báo ngầm (notification).
  • Bạn muốn code gọn gàng, tránh việc lạm dụng quá nhiều khối try-catch làm rối mắt logic nghiệp vụ (business logic).

❌ Không nên dùng khi:

  • Đó là các giao dịch cốt lõi (critical transactions) như thanh toán ngân hàng, chuyển tiền, hay tạo đơn hàng. Những nơi này đòi hỏi bạn phải bắt chính xác lỗi, rollback database transaction (DB::rollBack()), hoặc ném ra các mã lỗi cụ thể (ErrorCodeException) để thông báo trực tiếp cho người dùng.

Tổng kết

Hàm rescue() là một minh chứng cho thấy sự tinh tế của Laravel trong việc tối ưu hóa Developer Experience (DX). Bằng cách biến một khối try-catch cồng kềnh thành một dòng code ngắn gọn, rescue() giúp mã nguồn của bạn sạch hơn, dễ đọc hơn và chuyên nghiệp hơn rất nhiều.


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.