---
title: Khối catch phải log nguyên nhân gốc rễ của lỗi
impact: HIGH
impactDescription: Bắt lỗi mà không log làm mất hoàn toàn thông tin debug, khiến việc tìm nguyên nhân sự cố trở nên rất khó.
tags: swift, ios, error-handling, logging, debugging, do-catch
---

## Khối catch phải log nguyên nhân gốc rễ của lỗi

Mỗi `catch` block phải ghi log đầy đủ thông tin: loại lỗi, ngữ cảnh (userId, orderId...) và stack trace khi cần. Không bao giờ bắt lỗi mà không làm gì (silent fail). Dùng `os.Logger` hoặc logging framework thay cho `print()`.

**Incorrect (bắt lỗi im lặng hoặc thiếu thông tin):**

```swift
import OSLog

func loadUserData(userId: String) async {
    do {
        let user = try await apiService.fetchUser(userId: userId)
        displayUser(user)
    } catch {
        // !! Silent fail - mất hoàn toàn lỗi
    }
}

func saveOrder(_ order: Order) {
    do {
        try coreDataManager.save(order)
    } catch {
        print("Error saving") // Không có context, không có error detail
    }
}
```

**Correct (log đầy đủ context):**

```swift
import OSLog

private let logger = Logger(subsystem: "com.app.user", category: "DataLoader")

func loadUserData(userId: String) async {
    do {
        let user = try await apiService.fetchUser(userId: userId)
        displayUser(user)
    } catch let apiError as APIError {
        // Log lỗi có type + context
        logger.error("Failed to fetch user. userId=\(userId), error=\(apiError.code): \(apiError.localizedDescription)")
        showErrorBanner(message: apiError.userMessage)
    } catch {
        // Lỗi unexpected - log đầy đủ
        logger.error("Unexpected error loading user. userId=\(userId), error=\(error)")
        showErrorBanner(message: "Không thể tải thông tin người dùng.")
    }
}

func saveOrder(_ order: Order) {
    do {
        try coreDataManager.save(order)
        logger.info("Order saved successfully. orderId=\(order.id)")
    } catch {
        logger.error("Failed to save order. orderId=\(order.id), error=\(error)")
        showSaveFailedAlert()
    }
}
```

**Tools:** `os.Logger`, SwiftLint custom rule, Code Review

