Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

ما هو خطأ وقت التشغيل (Runtime Error)؟

خطأ وقت التشغيل (runtime error) هو خطأ يقع أثناء تشغيل البرنامج، عندما تتعذر عملية ما بالقيم المتاحة لها، مثل القسمة على صفر أو القراءة بعد نهاية القائمة. يتوقف البرنامج عند ذلك السطر ما لم يُعالَج الخطأ.

بقلم Kevin Spektor, شريك مؤسس ورئيس قسم التكنولوجيا (CTO)

آخر تحديث 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) صفرًا ولا يمكن إجراء القسمة. لم يكن في القواعد النحوية أي خلل، فهذا ليس خطأً في الصياغة. المشكلة موجودة فقط مع بيانات معينة، ولهذا قد يظهر خطأ وقت التشغيل بعد أن يعمل البرنامج بشكل صحيح مئة مرة.

ماذا يحدث عند وقوع خطأ وقت التشغيل

  1. يصل البرنامج إلى عملية ما، وهي هنا sum(scores) / len(scores).
  2. تفحص بيئة التشغيل العملية قبل تنفيذها. يختبر CPython المقسوم عليه قبل القسمة، وتفحص JVM كل فهرس في المصفوفة، وتتحقق بايثون من وجود مفتاح القاموس قبل إرجاع قيمته.
  3. يفشل الفحص، فتُنشئ بيئة التشغيل كائن خطأ. في بايثون وجافا يكون هذا الكائن استثناءً، ويسجل نوع الخطأ ورسالة وموضع وقوعه.
  4. تبحث بيئة التشغيل عن كود يعالج هذا النوع من الأخطاء، أولًا في الدالة الحالية، ثم في الدالة التي استدعتها، وهكذا إلى الخارج.
  5. إن لم يعالجه شيء، يتوقف البرنامج. تطبع بايثون 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.

الخطأمثالالرسالة
ZeroDivisionError10 / 0division by zero
IndexError["red", "green", "blue"][3]list index out of range
KeyError{"theme": "dark"}["font"]'font'
ValueErrorint("twenty")invalid literal for int() with base 10: 'twenty'
TypeError"Total: " + 5can only concatenate str (not "int") to str
AttributeErrorاستدعاء .upper() على None'NoneType' object has no attribute 'upper'
FileNotFoundErroropen("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')

كيف تصلح خطأ وقت التشغيل

  1. أعِد إنتاجه. شغّل البرنامج مرة أخرى بالمدخل نفسه وتأكد من ظهور الخطأ نفسه.
  2. اقرأ السطر الأخير من الـ traceback، ثم جد السطر المقابل في كودك أنت.
  3. انظر إلى القيم المعنية. اطبعها قبل السطر الفاشل مباشرة، أو توقف عنده بنقطة توقف (breakpoint) في المُنقِّح.
  4. أصلح السبب. صحّح الفهرس، أو احمِ الحالة الخاصة، أو تحقق من صحة المدخل قبل استخدامه.

في دالة 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؟
تعني أن حلك تُرجم بنجاح لكنه تعطل في حالة اختبار واحدة على الأقل. الأسباب المعتادة هي فهرس خارج النطاق، أو القسمة على صفر، أو استخدام قيمة null أو None، أو استدعاء ذاتي عميق جدًا يؤدي إلى فيضان المكدس. شغّل بنفسك المدخل الفاشل المعروض في صفحة النتائج، وافحص الحالات الحدية: مصفوفة فارغة، وعنصر واحد، وأكبر حجم مسموح.
هل خطأ وقت التشغيل هو نفسه الاستثناء؟
ليس تمامًا. في بايثون وجافا يُبلَّغ عن معظم أخطاء وقت التشغيل على شكل استثناءات، وهذا ما يتيح للبرنامج التقاطها. لكن لغات مثل C فيها أخطاء وقت تشغيل ولا استثناءات فيها على الإطلاق. وفي جافا، RuntimeException هو أيضًا اسم عائلة محددة من الاستثناءات، هي الاستثناءات غير المُتحقَّق منها مثل NullPointerException.
هل يستطيع المترجم اكتشاف أخطاء وقت التشغيل؟
بعضها فقط. يستطيع المترجم أو مدقق الأنواع مثل mypy أن يثبت استحالة أخطاء معينة، كجمع نص مع رقم. لكنه لا يعرف القيم التي تصل أثناء تشغيل البرنامج، مثل رقم يكتبه المستخدم ويتبين أنه صفر. هذه الأخطاء لا تُكتشف إلا بتشغيل الكود، أو تُعالج بفحص المدخلات.
Coddy programming languages illustration

تعلّم البرمجة مع Coddy

ابدأ الآن