---
title: Không throw lỗi generic - dùng Error enum có ngữ cảnh
impact: MEDIUM
impactDescription: Lỗi generic không cung cấp đủ thông tin để debug, xử lý hay hiển thị thông báo phù hợp cho người dùng.
tags: swift, ios, error-handling, enum, code-quality
---

## Không throw lỗi generic - dùng Error enum có ngữ cảnh

Không dùng `NSError`, `Error` chung chung hay string message tùy tiện. Thay vào đó, định nghĩa enum conform protocol `Error` với từng case cụ thể, mô tả rõ trường hợp thất bại.

**Incorrect (lỗi generic):**

```swift
func login(email: String, password: String) throws -> User {
    guard !email.isEmpty else {
        throw NSError(domain: "error", code: 400, userInfo: nil) // không có ngữ cảnh
    }
    guard isValidEmail(email) else {
        throw NSError(domain: "Invalid email", code: 0, userInfo: nil)
    }
    // ...
}
```

**Correct (Error enum mô tả rõ ràng):**

```swift
enum AuthError: Error, LocalizedError {
    case emptyCredentials
    case invalidEmailFormat
    case incorrectPassword
    case accountLocked(remainingAttempts: Int)
    case networkUnavailable

    var errorDescription: String? {
        switch self {
        case .emptyCredentials:
            return "Email và mật khẩu không được để trống."
        case .invalidEmailFormat:
            return "Định dạng email không hợp lệ."
        case .incorrectPassword:
            return "Mật khẩu không đúng."
        case .accountLocked(let attempts):
            return "Tài khoản bị khóa. Còn \(attempts) lần thử."
        case .networkUnavailable:
            return "Không có kết nối mạng."
        }
    }
}

func login(email: String, password: String) throws -> User {
    guard !email.isEmpty, !password.isEmpty else {
        throw AuthError.emptyCredentials
    }
    guard isValidEmail(email) else {
        throw AuthError.invalidEmailFormat
    }
    // ...
}
```

**Tools:** Code Review, SwiftLint

