© 2026 Laravel

Fail Fast là gì? Áp dụng nguyên tắc fail fast trong PHP & Laravel từ code đến system design

4 phút đọc 46 lượt xem
#fail-fast #error-handling #validation

“Fail early, fail loudly, fail clearly”

#Phần 1: Bản chất thật sự của Fail Fast

Fail Fast KHÔNG chỉ là:

  • throw exception

Fail Fast là:

  • Phát hiện lỗi càng sớm càng tốt
  • Dừng hệ thống ngay khi state không hợp lệ

#Ví dụ bản chất

function withdraw($amount) {
    // ❌ sai
    // xử lý tiếp dù amount invalid
}
function withdraw($amount) {
    if ($amount <= 0) {
        throw new Exception('Invalid amount');
    }
}

→ Fail ngay từ đầu

#Phần 2: Bad Example (PHP thuần)

class OrderProcessor {

    public function process(array $order) {

        // ❌ không validate
        $customer = $this->findCustomer($order['customer_id']);

        // ❌ có thể null
        $total = 0;

        foreach ($order['items'] ?? [] as $item) {
            $product = $this->findProduct($item['product_id']);

            if ($product) {
                $total += $product['price'] * ($item['quantity'] ?? 1);
            }
        }

        // ❌ vẫn tiếp tục
        $this->createOrder($order, $total);
    }
}

#Vấn đề

  • Lỗi bị che giấu
  • State không nhất quán
  • Debug cực khó

#Phần 3: Refactor (PHP thuần)

#Step 1: Validate input ngay lập tức

private function validate(array $input): array {
    if (!isset($input['customer_id'])) {
        throw new Exception('customer_id required');
    }

    if (!isset($input['items']) || empty($input['items'])) {
        throw new Exception('items required');
    }

    return $input;
}

#Step 2: Validate dependency

private function getCustomer($id) {
    $customer = $this->repo->find($id);

    if (!$customer) {
        throw new Exception('Customer not found');
    }

    return $customer;
}

#Step 3: Validate business rule

private function checkStock($items) {
    foreach ($items as $item) {
        $product = $this->findProduct($item['product_id']);

        if (!$product) {
            throw new Exception('Product not found');
        }

        if ($product['stock'] < $item['quantity']) {
            throw new Exception('Out of stock');
        }
    }
}

#Step 4: Orchestrate rõ ràng

public function process(array $input) {

    $input = $this->validate($input);

    $customer = $this->getCustomer($input['customer_id']);

    $this->checkStock($input['items']);

    $total = $this->calculateTotal($input['items']);

    return $this->createOrder($customer, $input, $total);
}

#Phân tích sâu

#1. Fail Fast = Guard Clause

  • Validate ở đầu function

#2. Fail Fast + Encapsulation

  • Object tự bảo vệ state

#3. Fail Fast + LSP

  • Preconditions phải được check

#4. Fail Fast = giảm side-effect

  • Không chạy logic khi data sai

#Phần 4: Error Design (rất quan trọng)

#❗ Không dùng Exception chung

throw new Exception('Error');

#✅ Custom Exception

class ValidationException extends Exception {}
class NotFoundException extends Exception {}
class BusinessException extends Exception {}

#Lợi ích

  • Phân loại lỗi
  • Handle riêng

#Phần 5: Mapping sang Laravel

#1. FormRequest = Fail Fast layer

class CreateOrderRequest extends FormRequest {
    public function rules() {
        return [
            'customer_id' => 'required|exists:customers,id',
            'items' => 'required|array|min:1'
        ];
    }
}

→ request fail trước khi vào controller

#2. Service layer validation

if ($product->stock < $qty) {
    throw new BusinessException('Out of stock');
}

#3. DB Transaction

DB::transaction(function () {
    // fail -> rollback
});

#4. Exception Handler

renderable(function (ValidationException $e) {
    return response()->json(['error' => $e->getMessage()], 400);
});

#Phần 6: Khi nào cần Fail Fast?

  • Input từ user
  • API boundary
  • Business rule

#Khi nào KHÔNG cần?

  • Logging không critical
  • Retry logic

#Pitfalls

#1. Fail too late

  • validate sau khi xử lý

#2. Fail too early (sai ngữ cảnh)

  • reject khi chưa cần

#3. Swallow exception

try {
} catch (Exception $e) {}

→ phá fail fast

#Advanced Insight (Staff level)

#1. Fail Fast vs Fail Safe

  • Fail Fast: dừng ngay
  • Fail Safe: fallback

→ cần phân biệt

#2. Fail Fast trong distributed system

  • Không phải lúc nào cũng throw
  • Có thể retry / circuit breaker

#3. Fail Fast = giảm blast radius

  • lỗi không lan rộng

#Câu hỏi phỏng vấn

1. Fail Fast là gì?

Summary:

  • Phát hiện lỗi sớm

Deep:

  • Tránh inconsistent state
2. Fail Fast khác gì Validation?

Summary:

  • Validation là 1 phần

Deep:

  • Fail Fast là mindset toàn system
3. Khi nào không nên Fail Fast?

Summary:

  • Khi cần resilience

Deep:

  • Retry, fallback

#Kết luận

Fail Fast không phải là:

  • throw exception bừa bãi

Mà là:

phát hiện lỗi sớm để bảo vệ hệ thống

Nếu hệ thống của bạn xử lý tiếp khi data sai → bạn đang tích lũy bug và technical debt.