AzLearn

أساسيات الأخطاء

Error Basics

مفهوم ~18 دقيقة

أساسيات الأخطاء — Error Basics

في أغلب اللغات، الأخطاء تُعالج عبر الاستثناءات (exceptions) — تُرمى في مكان وتُلتقط في مكان آخر. Go اختارت طريقاً مختلفاً تماماً: الأخطاء قيم عادية.

هذا يعني أنك تتعامل مع الخطأ كما تتعامل مع أي قيمة — تفحصه، تمرره، تغلّفه، أو تتجاهله (وهذا خطأ!).

واجهة error

error هو نوع مُدمج في Go — واجهة بأسلوب واحد:

type error interface {
    Error() string
}

أي نوع يُنفّذ Error() string يُعتبر خطأ. بهذه البساطة.

إنشاء أخطاء بسيطة

main.go

نمط if err != nil

هذا هو النمط الأساسي في Go — ستراه في كل مكان:

result, err := someFunction()
if err != nil {
    // تعامل مع الخطأ — Handle the error
    return err  // أو log أو retry
}
// استخدم result — Use result

نعم، هذا يعني كتابة if err != nil كثيراً. مجتمع Go يرى أن هذا ميزة وليس عيب — لأنه يجبرك على التفكير في كل حالة خطأ بدلاً من تجاهلها.

تغليف الأخطاء — Error Wrapping مع %w

عندما تلتقط خطأ من دالة داخلية وتريد إضافة سياق، استخدم %w:

main.go

لاحظ كيف أن %w يحفظ الخطأ الأصلي داخل الخطأ الجديد — مما يسمح لنا بفحصه لاحقاً بـ errors.Is.

الفرق بين %v و %w

// %v — ينسخ الرسالة فقط، يفقد الخطأ الأصلي
fmt.Errorf("فشل: %v", err)  // لا يمكن استخدام errors.Is بعدها

// %w — يغلّف الخطأ الأصلي، يحفظه
fmt.Errorf("فشل: %w", err)  // يمكن استخدام errors.Is

القاعدة: استخدم %w عندما تريد أن يبقى الخطأ الأصلي قابلاً للفحص.

تجاهل الأخطاء — Don’t!

أحد أخطر الأخطاء في Go هو تجاهل القيمة المُرجعة:

// ❌ خطير — تجاهل الخطأ
result, _ := riskyFunction()

// ✅ صحيح — تعامل مع الخطأ
result, err := riskyFunction()
if err != nil {
    log.Fatal(err)
}

تجاهل الخطأ مقبول فقط عندما تكون متأكداً تماماً أنه لن يحدث، أو أنك لا تهتم بالنتيجة (مثل fmt.Println التي نادراً ما تفشل).

أنماط شائعة

1. الإرجاع المبكر — Early return:

func processFile(path string) error {
    data, err := readFile(path)
    if err != nil {
        return fmt.Errorf("قراءة الملف: %w", err)
    }

    result, err := parse(data)
    if err != nil {
        return fmt.Errorf("تحليل البيانات: %w", err)
    }

    return save(result)
}

2. التجميع — collecting errors:

main.go
تحدي — Challenge