recover
التقاط panic والتعافي منه recover
recover تلتقط panic جاريًا وتوقف سلسلة الإنهاء، لتعيد البرنامج للتنفيذ الطبيعي بدل الانهيار الكامل — لكنها تعمل فقط داخل دالة مؤجَّلة بـ defer.
recover مفيدة فقط عند استدعائها مباشرة داخل دالة مؤجَّلة بـ defer. لو كانت الـ goroutine الحالية تمرّ بحالة panic، يوقف recover سلسلة الإنهاء ويعيد التنفيذ لوضعه الطبيعي، ويعيد القيمة التي مُرِّرت لـ panic الأصلية. استدعاء recover خارج دالة مؤجَّلة، أو حين لا توجد panic جارية أصلًا، لا يفعل شيئًا ويعيد nil فقط.
هذا النمط شائع بخوادم HTTP: التقاط panic بأي معالج طلب كي لا يُسقط panic واحد الخادم كاملًا، مع تسجيل الخطأ والاستمرار بخدمة الطلبات الأخرى.
الصياغة
func recover() any
defer func() {
if r := recover(); r != nil {
// تعامل مع القيمة r
}
}()📄 مثال
func safeCall() {
defer func() {
if r := recover(); r != nil {
fmt.Println("تعافٍ من:", r)
}
}()
panic("خطأ فادح غير متوقّع")
}
safeCall()
fmt.Println("البرنامج يكمل عاديًا بعد التعافي")أهم النقاط
| العنصر | الوظيفة |
|---|---|
| recover() | يلتقط panic الجارية ويعيد القيمة المُمرَّرة لها، أو nil إن لم توجد panic |
| داخل defer فقط | استدعاؤه خارج دالة مؤجَّلة مباشرة لا يوقف أي panic |
💡 نصائح عملية
- استخدم recover عند حدود واضحة فقط (مثل معالج HTTP أو نقطة دخول worker)، لا بكل دالة — كثرته يخفي أخطاء برمجية حقيقية بدل إصلاحها
- سجّل قيمة recover() دائمًا (بسجلّ أو مراقبة) قبل تجاهلها — panic ملتقطة بصمت تخفي مشاكل حقيقية
⚠️ أخطاء شائعة
- استدعاء recover() بدالة عادية بدل دالة مؤجَّلة مباشرة — لا يلتقط شيئًا في هذه الحالة
- استخدام recover كبديل دائم لمعالجة الأخطاء بدل إصلاح السبب الجذري لحدوث panic أصلًا
خصائص ذات صلة
🎓 تريد فهم الصورة الكاملة خطوة بخطوة؟ ابدأ من مسار GO الكامل بالعربي.