مدیریت خطاها (Errors)

مدیریت خطا در Go: error، errors.New، fmt.Errorf و الگوهای رایج.

فلسفه خطا در Go

Go برخلاف Java/Python از exception استفاده نمی‌کند! به جای try/catch، خطاها مقدار بازگشتی هستند:

result, err := doSomething()
if err != nil {
    // خطا رخ داد
}

نوع error

error یک اینترفیس داخلی است:

type error interface {
    Error() string
}

ساخت خطا

با errors.New

import "errors"

err := errors.New("خطای ساده")

با fmt.Errorf — با قالب‌بندی

err := fmt.Errorf("عدد %d خارج از محدوده است", 42)

با %w — پیچیدن خطا (Wrapping)

if err := readConfig(); err != nil {
    return fmt.Errorf("خواندن تنظیمات: %w", err)   ← خطای اصلی حفظ می‌شود
}

الگوی استاندارد

func divide(a, b float64) (float64, error) {
    if b == 0 {
        return 0, fmt.Errorf("تقسیم بر صفر")
    }
    return a / b, nil   ← nil یعنی بدون خطا
}

بررسی خطا

result, err := divide(10, 0)
if err != nil {
    fmt.Println("خطا:", err)
    return   ← معمولاً return یا os.Exit
}
fmt.Println("نتیجه:", result)

بررسی خطای خاص با errors.Is

var ErrNotFound = errors.New("پیدا نشد")

func find(id int) error {
    return ErrNotFound
}

err := find(42)
if errors.Is(err, ErrNotFound) {
    fmt.Println("رکورد وجود ندارد")
}

خطای سفارشی (Custom Error)

type AppError struct {
    Code    int
    Message string
}

func (e *AppError) Error() string {
    return fmt.Sprintf("[%d] %s", e.Code, e.Message)
}

return &AppError{Code: 404, Message: "یافت نشد"}
هرگز خطا را _ نکنید مگر مطمئن باشید — خطاهای نادیده‌گرفته‌شده منبع باگ‌های سخت‌یاب هستند!

چرا این روش بهتر است؟

این مبحث بخشی از دوره آموزش کامل گو است.

ابزارهای مرتبط