KHOÁ HỌC Phần 2 — 20% còn lại Error handling nâng cao

Error handling nâng cao

D1. Custom Error Types

type NotFoundError struct {
    Resource string
    ID       int
}

func (e *NotFoundError) Error() string {
    return fmt.Sprintf("%s ID=%d không tồn tại", e.Resource, e.ID)
}

// Dùng
return &NotFoundError{Resource: "User", ID: 42}

Sentinel errors — hằng số lỗi

var ErrNotFound = errors.New("not found")

if err == ErrNotFound { ... }

D2. errors.Iserrors.As

Sau khi wrap lỗi với %w, muốn kiểm tra lỗi gốc:

err := fmt.Errorf("query failed: %w", ErrNotFound)

// errors.Is — check "lỗi này CÓ PHẢI ErrNotFound không?"
if errors.Is(err, ErrNotFound) { ... }

// errors.As — check "lỗi này CÓ THUỘC loại *NotFoundError không?"
var nfe *NotFoundError
if errors.As(err, &nfe) {
    fmt.Println("Resource:", nfe.Resource)
}

D3. panic & recover

panic — dừng chương trình

if config == nil {
    panic("config bị nil, không thể chạy")
}

recover — bắt panic (chỉ dùng trong defer)

func safeRun() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Đã bắt panic:", r)
        }
    }()

    panic("boom!")
}

👉 Nguyên tắc: panic chỉ dùng cho lỗi không thể phục hồi. Đừng dùng như try/catch của Java.

← Type system nâng cao