ما هو خطأ وقت التشغيل (Runtime Error)؟
خطأ وقت التشغيل (runtime error) هو خطأ يقع أثناء تشغيل البرنامج، عندما تتعذر عملية ما بالقيم المتاحة لها، مثل القسمة على صفر أو القراءة بعد نهاية القائمة. يتوقف البرنامج عند ذلك السطر ما لم يُعالَج الخطأ.
آخر تحديث 24 سبتمبر 2026
ينتظر خطأ وقت التشغيل حتى يكون البرنامج قد بدأ العمل بالفعل. يجتاز الكود كل الفحوص قبل أن يبدأ، ويعمل بشكل صحيح لبعض الوقت، ثم يصل إلى عملية لا يمكن تنفيذها بالقيم التي يملكها في تلك اللحظة. هذه الدالة تعمل مع قائمة وتفشل مع أخرى:
85.0
Traceback (most recent call last):
File "main.py", line 5, in <module>
print(average([]))
^^^^^^^^^^^
File "main.py", line 2, in average
return sum(scores) / len(scores)
~~~~~~~~~~~~^~~~~~~~~~~~~
ZeroDivisionError: division by zero
الاستدعاء الأول يطبع 85.0. أما الثاني فيمرر قائمة فارغة، فتكون قيمة len(scores) صفرًا ولا يمكن إجراء القسمة. لم يكن في القواعد النحوية أي خلل، فهذا ليس خطأً في الصياغة. المشكلة موجودة فقط مع بيانات معينة، ولهذا قد يظهر خطأ وقت التشغيل بعد أن يعمل البرنامج بشكل صحيح مئة مرة.
ماذا يحدث عند وقوع خطأ وقت التشغيل
- يصل البرنامج إلى عملية ما، وهي هنا
sum(scores) / len(scores). - تفحص بيئة التشغيل العملية قبل تنفيذها. يختبر CPython المقسوم عليه قبل القسمة، وتفحص JVM كل فهرس في المصفوفة، وتتحقق بايثون من وجود مفتاح القاموس قبل إرجاع قيمته.
- يفشل الفحص، فتُنشئ بيئة التشغيل كائن خطأ. في بايثون وجافا يكون هذا الكائن استثناءً، ويسجل نوع الخطأ ورسالة وموضع وقوعه.
- تبحث بيئة التشغيل عن كود يعالج هذا النوع من الأخطاء، أولًا في الدالة الحالية، ثم في الدالة التي استدعتها، وهكذا إلى الخارج.
- إن لم يعالجه شيء، يتوقف البرنامج. تطبع بايثون traceback وتخرج بالحالة 1، وتطبع جافا stack trace يبدأ بـ
Exception in thread "main".
اللغات التي تخلو من هذه الفحوص تتصرف بشكل مختلف. لغة C لا تفحص فهارس المصفوفات ولا المؤشرات، فالوصول الخاطئ إلى الذاكرة إما أن يُفسد البيانات بصمت، وإما أن يجعل نظام التشغيل يُنهي البرنامج بـ خطأ التجزئة.
كل ما فعله البرنامج قبل السطر الفاشل قد حدث بالفعل. هذه الحلقة تطبع ثلاثة ألوان قبل أن تفشل عند الرابع:
red
green
blue
Traceback (most recent call last):
File "main.py", line 4, in <module>
print(colors[i])
~~~~~~^^^
IndexError: list index out of range
كيف تقرأ الـ traceback
اقرأ الـ traceback في بايثون من الأسفل إلى الأعلى. السطر الأخير يذكر نوع الخطأ والرسالة: ZeroDivisionError: division by zero. والأسطر التي فوقه تسرد سلسلة الاستدعاءات، الأقدم أولًا والأحدث أخيرًا. في المثال الأول استدعى السطر 5 الدالة average، والسطر 2 داخل average هو الموضع الذي فشلت فيه القسمة.
السطر الذي وقع فيه الخطأ ليس دائمًا السطر الذي يجب تغييره. السطر 2 من average صحيح. السؤال الحقيقي هو كيف وصلت إليه قائمة فارغة، فتتبّع القيمة الخاطئة إلى مصدرها وأصلحها هناك. وعندما يمر الـ traceback بملفات مكتبات لم تكتبها، ابحث عن آخر سطر يشير إلى ملفك أنت.
أشهر أخطاء وقت التشغيل
كل رسالة من هذه الرسائل منقولة من بايثون 3.12.
| الخطأ | مثال | الرسالة |
|---|---|---|
ZeroDivisionError | 10 / 0 | division by zero |
IndexError | ["red", "green", "blue"][3] | list index out of range |
KeyError | {"theme": "dark"}["font"] | 'font' |
ValueError | int("twenty") | invalid literal for int() with base 10: 'twenty' |
TypeError | "Total: " + 5 | can only concatenate str (not "int") to str |
AttributeError | استدعاء .upper() على None | 'NoneType' object has no attribute 'upper' |
FileNotFoundError | open("missing.txt") | [Errno 2] No such file or directory: 'missing.txt' |
RecursionError | دالة تستدعي نفسها إلى ما لا نهاية | maximum recursion depth exceeded |
لجافا مقابلات مباشرة، مثل ArithmeticException وArrayIndexOutOfBoundsException وNumberFormatException وNullPointerException. قسمة عدد صحيح على صفر لا يلتقطها شيء تطبع هذا في جافا:
Exception in thread "main" java.lang.ArithmeticException: / by zero
جافا سكريبت أكثر تساهلًا مع الأرقام: 10 / 0 تساوي Infinity وليست خطأً. لكنها تفشل عندما تستخدم قيمة غير موجودة. يطبع Node.js هذا عند user.name حين تكون user قيمتها undefined:
TypeError: Cannot read properties of undefined (reading 'name')
كيف تصلح خطأ وقت التشغيل
- أعِد إنتاجه. شغّل البرنامج مرة أخرى بالمدخل نفسه وتأكد من ظهور الخطأ نفسه.
- اقرأ السطر الأخير من الـ traceback، ثم جد السطر المقابل في كودك أنت.
- انظر إلى القيم المعنية. اطبعها قبل السطر الفاشل مباشرة، أو توقف عنده بنقطة توقف (breakpoint) في المُنقِّح.
- أصلح السبب. صحّح الفهرس، أو احمِ الحالة الخاصة، أو تحقق من صحة المدخل قبل استخدامه.
في دالة average، يكون الإصلاح بأن تقرر ما يجب أن يكون عليه متوسط قائمة بلا درجات، وتقول ذلك صراحةً في الكود:
85.0
0
بعض الأعطال خارج سيطرتك: ملف حُذف، أو شبكة انتهت مهلتها، أو مستخدم يكتب حروفًا مكان رقم. لا يمكنك منع هذه بإصلاح الكود، لذا تلتقطها بـ معالجة الاستثناءات وتقرر ما يفعله البرنامج بعدها. ما لا ينبغي فعله هو تغليف خلل برمجي بـ try لإخفائه. فخطأ IndexError من حلقة تعدّ خطوة زائدة هو خطأ يجب إصلاحه، لا خطأ يجب التقاطه.
رسائل خطأ وقت التشغيل في ويندوز و Excel
يظهر المصطلح أيضًا خارج كودك. نافذة في ويندوز عنوانها Microsoft Visual C++ Runtime Library وفيها عبارة Runtime Error! تعني أن برنامجًا مكتوبًا بلغة C++ واجه خطأً قاتلًا فأنهته بيئة تشغيل C++. وبما أنك كمستخدم لا تستطيع تغيير ذلك الكود، فالحلول المعتادة هي تحديث البرنامج، وإصلاح حزم Microsoft Visual C++ Redistributable أو إعادة تثبيتها، وتحديث تعريف بطاقة الرسومات في حالة الألعاب.
وحدات الماكرو في Excel المكتوبة بلغة VBA تُبلغ عن أخطاء وقت تشغيل مرقّمة. Run-time error '9': Subscript out of range تعني أن الماكرو طلب ورقة عمل أو عنصر مصفوفة غير موجود، وRun-time error '1004' خطأ عام يُرفع عندما تفشل عملية على مصنف أو ورقة أو نطاق. والفكرة هي نفسها كما في بايثون: كود سليم صادف قيمة لم يستطع التعامل معها.
إلى أين بعد ذلك
لأخطاء وقت التشغيل شقيقان: الخطأ في الصياغة الذي يُكتشف قبل أن يبدأ البرنامج، والخطأ المنطقي الذي لا يُنتج أي رسالة على الإطلاق. ولتتعافى من أخطاء وقت التشغيل بدل أن يتعطل البرنامج، اقرأ عن معالجة الاستثناءات، ثم أدلة بايثون عن الاستثناءات وتصحيح الأخطاء. وفي دورة بايثون تكتب كودًا كهذا وتصلحه في كل درس.
الأسئلة الشائعة
ما الفرق بين خطأ وقت التشغيل وخطأ الصياغة؟
لماذا تتكرر معي أخطاء وقت التشغيل؟
ماذا تعني رسالة Runtime Error في LeetCode؟
None، أو استدعاء ذاتي عميق جدًا يؤدي إلى فيضان المكدس. شغّل بنفسك المدخل الفاشل المعروض في صفحة النتائج، وافحص الحالات الحدية: مصفوفة فارغة، وعنصر واحد، وأكبر حجم مسموح.هل خطأ وقت التشغيل هو نفسه الاستثناء؟
RuntimeException هو أيضًا اسم عائلة محددة من الاستثناءات، هي الاستثناءات غير المُتحقَّق منها مثل NullPointerException.