كيف تقرأ رسائل الخطأ

يتجمّد المبتدئون حين يرون نصًا أحمر. لا تفعل ذلك؛ فرسائل الخطأ تخبرك بالضبط بما حدث من خلل.

تشريح خطأ Python

Traceback (most recent call last):
  File "/home/user/app.py", line 5, in <module>
    result = divide(10, 0)
             ^^^^^^^^^^^^^
  File "/home/user/app.py", line 2, in divide
    return a / b
           ~~^~~
ZeroDivisionError: division by zero

اقرأه من الأسفل إلى الأعلى:

  1. السطر الأخير: نوع الخطأ + الرسالة → ZeroDivisionError: division by zero
  2. ما فوقه: السطر الذي تسبّب في الخطأ → return a / b في السطر 2
  3. ما فوقه: سلسلة استدعاء الدوال (تتبع الأخطاء) → divide(10, 0) في السطر 5

أخطاء شائعة ومعانيها

خطأ ModuleNotFoundError

ModuleNotFoundError: No module named 'flask'

الإصلاح: ثبّت الحزمة الناقصة:

pip install flask

أو فعّل بيئتك الافتراضية إن كانت الحزمة مثبّتة فيها بالفعل.

خطأ ImportError

ImportError: cannot import name 'jsonify' from 'flask'

الإصلاح: ربما اسم الحزمة أو إصدارها غير صحيح. تحقق من جملة الاستيراد ومن الإصدار المثبّت لديك.

خطأ SyntaxError

  File "script.py", line 3
    print("hello"
                 ^
SyntaxError: unexpected EOF while parsing

الإصلاح: ينقصك قوس إغلاق ) أو قوس مربّع. عُدّ الأقواس.

خطأ NameError

NameError: name 'app' is not defined

الإصلاح: استخدمت متغيّرًا قبل تعريفه. تحقق من الإملاء — هل كنت تقصد app أم App؟

خطأ TypeError

TypeError: unsupported operand type(s) for +: 'int' and 'str'

الإصلاح: حاولت جمع رقم بسلسلة نصية. حوّل أحدهما:

str(5) + " apples"   # "5 apples"
5 + int("3")          # 8

خطأ IndexError

IndexError: list index out of range

الإصلاح: حاولت الوصول إلى فهرس غير موجود. فهارس القوائم تبدأ من 0:

items = ["a", "b"]
items[0]  # "a" — صحيح
items[2]  # خطأ! لا يوجد سوى الفهرسين 0 و 1

خطأ KeyError

KeyError: 'username'

الإصلاح: حاولت الوصول إلى مفتاح غير موجود في قاموس. استخدم .get() للوصول الآمن:

user = {"name": "Alice"}
user["name"]        # "Alice" — صحيح
user.get("age")     # None — آمن
user["age"]         # KeyError!

خطأ JSONDecodeError

json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

الإصلاح: حاولت تحليل استجابة فارغة أو غير مكوّنة من JSON. تحقق من وجود نقطة النهاية (endpoint) في API وأنها تعيد JSON صالحًا. اطبع الاستجابة الخام أولًا:

print(response.text)  # انظر إلى ما تحصل عليه فعلًا

خطأ ConnectionError / ConnectionRefusedError

ConnectionRefusedError: [Errno 61] Connection refused

الإصلاح: حاولت الاتصال بخادم غير قيد التشغيل. شغّل الخادم أولًا، ثم شغّل عميلك.

عملية تصحيح الأخطاء في 5 خطوات

  1. اقرأ السطر الأخير أولًا — ما نوع الخطأ؟
  2. اعثر على الملف ورقم السطر — أين وقع الخطأ؟
  3. انظر إلى السطر — هل ترى الخطأ المطبعي أو موضع الخلل؟
  4. أضف عبارات طباعة — اطبع المتغيّرات لترى ما تحتويه
  5. انسخ الخطأ إلى Google — إن واجهت صعوبة، فانسخ رسالة الخطأ (دون المسارات المحددة) وألصقها في Google

نصيحة احترافية: اطبع كل شيء

حين لا يعمل شيء ما، أضف عبارات طباعة:

print(f"DEBUG: variable value is: {my_var}")
print(f"DEBUG: type is: {type(my_var)}")
print(f"DEBUG: response text is: {response.text}")

هذه أكثر تقنيات التصحيح فاعلية على الإطلاق.