Exception Handling

✅ ما هو Exception Handling في Dart؟

هو آلية لإدارة الأخطاء التي قد تحدث أثناء تنفيذ البرنامج، بدل أن يتوقف البرنامج فجأة.

🧩 الكلمات الأساسية:
الكلمةالمعنى
tryتجرب تنفيذ كود معين قد يسبب خطأ
catchالتقاط ومعالجة الخطأ إذا حدث
onالتقاط نوع معين من الأخطاء
finallyينفذ دائمًا، سواء حدث خطأ أو لا
throwلرمي (إطلاق) خطأ مخصص يدويًا
أنواع الاستثناءات (Exceptions) المدمجة في Dart
نوع الاستثناءمتى يحدث؟
FormatExceptionعند محاولة تحويل نص إلى رقم بشكل غير صحيح
IntegerDivisionByZeroExceptionعند قسمة عدد صحيح على صفر باستخدام ~/
RangeErrorعند الوصول إلى فهرس خارج حدود قائمة
ArgumentErrorعندما يتم تمرير قيمة غير صحيحة كمعامل (parameter)
UnsupportedErrorعند محاولة استخدام ميزة غير مدعومة
UnimplementedErrorدالة لم تُطبق بعد
StateErrorاستخدام كائن في حالة غير مناسبة
NoSuchMethodErrorاستدعاء دالة أو خاصية غير موجودة
CastErrorمحاولة تحويل كائن إلى نوع غير مناسب
TypeErrorعند حدوث خطأ في النوع أثناء التشغيل
🧪 أولاً: try - catch
✅ المثال:
void main() {
  try {
    int result = 10 ~/ 0; // خطأ: قسمة على صفر
    print(result);
  } catch (e) {
    print('حدث خطأ: $e');
  }
}
Dart
✅ الناتج:
حدث خطأ: IntegerDivisionByZeroException
Dart
✅ الفائدة:
  • يمنع البرنامج من التوقف.
  • يسمح لك بإظهار رسالة للمستخدم أو تسجيل الخطأ.

🔸 1. FormatException

void main() {
  try {
    int x = int.parse("abc");
  } catch (e) {
    print("خطأ: $e"); // FormatException
  }
}
Dart
🔸 2. IntegerDivisionByZeroException
void main() {
  try {
    int x = 10 ~/ 0;
  } catch (e) {
    print("خطأ: $e"); // IntegerDivisionByZeroException
  }
}
Dart

🔸 3. RangeError

void main() {
  try {
    var list = [1, 2, 3];
    print(list[5]);
  } catch (e) {
    print("خطأ: $e"); // RangeError
  }
}
Dart

🔸 4. ArgumentError

void printPositive(int number) {
  if (number < 0) throw ArgumentError("الرقم يجب أن يكون موجبًا");
  print(number);
}

void main() {
  try {
    printPositive(-5);
  } catch (e) {
    print("خطأ: $e"); // ArgumentError
  }
}
Dart
🧩 ثانياً: on — لمعالجة أخطاء من نوع معين
void main() {
  try {
    int result = 10 ~/ 0;
    print(result);
  } on IntegerDivisionByZeroException {
    print("لا يمكن القسمة على صفر!");
  }
}
Dart
✅ الفرق بين on و catch:
oncatch
يستخدم لنوع خطأ محدديستخدم لأي خطأ
لا يُظهر تفاصيل الخطأ تلقائيًايمكنك الحصول على تفاصيل e
🧩 ثالثاً: catch مع تفاصيل الخطأ
void main() {
  try {
    List<int> nums = [1, 2];
    print(nums[5]); // ❌ خطأ: فهرس غير موجود
  } catch (e, stackTrace) {
    print("الخطأ: $e");
    print("تفاصيل: $stackTrace");
  }
}
Dart
  • e: هو نوع الخطأ.
  • stackTrace: أين حدث الخطأ في الكود.
🧩 رابعاً: finally — ينفذ دائمًا
void main() {
  try {
    print("أقوم بتقسيم رقم...");
    int res = 10 ~/ 0;
    print(res);
  } catch (e) {
    print("حدث خطأ");
  } finally {
    print("تم تنفيذ finally");
  }
}
Dart
✅ الناتج:
أقوم بتقسيم رقم...
حدث خطأ
تم تنفيذ finally
Dart

✅ متى نستخدم finally؟

  • لغلق ملف، إيقاف مؤقت، تحرير موارد، إلخ.
🧩 خامساً: throw — لرمي خطأ يدويًا
void divide(int x, int y) {
  if (y == 0) {
    throw Exception("لا يمكن القسمة على صفر!");
  } else {
    print(x / y);
  }
}

void main() {
  try {
    divide(10, 0);
  } catch (e) {
    print("خطأ: $e");
  }
}
Dart
🧠 استخدام عملي متقدم:
✅ مثال: تحقق من عمر مستخدم
void checkAge(int age) {
  if (age < 18) {
    throw FormatException("العمر يجب أن يكون 18 أو أكثر.");
  }
  print("مرحبًا بك!");
}

void main() {
  try {
    checkAge(15);
  } on FormatException catch (e) {
    print("خطأ في التنسيق: ${e.message}");
  } finally {
    print("التحقق من العمر انتهى.");
  }
}
Dart
✅ ملخص الفرق بين الكلمات:
الكلمةالوظيفةهل مطلوبة؟
tryيحاول تنفيذ كود فيه خطأ محتمل✅ دائمًا مع catch/on
catchيلتقط أي خطأ ويعطي تفاصيلهاختياري (إما catch أو on)
onيعالج نوع خطأ معيناختياري
finallyينفذ في جميع الحالاتاختياري
throwلرمي استثناء يدويًااختياري (لكن مهم أحيانًا)
🎯 ممارسات جيدة:
  1. لا تترك catch فارغًا — دائمًا اعرض أو سجل الخطأ.
  2. لا تستخدم throw بدون داعٍ — فقط إذا كنت بحاجة لرمي خطأ منطقي.
  3. استخدم finally عند التعامل مع الملفات، قواعد البيانات، إلخ.
  4. حدد نوع الخطأ في on كلما أمكن — لتفادي التقاط أخطاء غير متوقعة.
هل Dart تسمح بإنشاء أنواع أخطاء مخصصة؟

نعم ✅

class AgeException implements Exception {
  final String message;
  AgeException(this.message);
}

void checkAge(int age) {
  if (age < 18) {
    throw AgeException("العمر صغير جدًا!");
  }
}
Dart