معالجة الأخطاء في TypeScript: تقنيات متقدمة لـ try/catch

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

معالجة الأخطاء في TypeScript: من try/catch الأساسي إلى الأنماط الصناعية

\n\n

معالجة الأخطاء ليست مجرد كتل try/catch. في TypeScript، بفضل نظام الأنواع الصارم، يمكننا الارتقاء بإدارة الأخطاء إلى مستوى جديد تمامًا. في هذه المقالة، سنستعرض التقنيات المتقدمة التي ستساعدك في كتابة كود أكثر موثوقية وقابلية للتنبؤ.

\n\n

مشكلة try/catch القياسي في TypeScript

\n\n

كتلة try/catch التقليدية في TypeScript تعاني من مشكلة أساسية: نوع الخطأ الذي يتم التقاطه هو unknown (أو any في الإصدارات القديمة). هذا يعني أن TypeScript لا يعرف بالضبط أي كائن نتعامل معه.

\n\n
try {\n  // بعض الكود الخطير\n  const result = JSON.parse('{"data": 123}');\n} catch (error) {\n  // error له نوع unknown\n  // لا يمكن ببساطة استدعاء error.message\n  console.log(error.message); // خطأ في الترجمة!\n}
\n\n

هذا يجبر المطورين إما على تجاهل الأنواع أو كتابة فحوصات ضخمة. دعنا نرى كيف نحل هذه المشكلة على مستوى متقدم.

\n\n

1. إنشاء نظام أخطاء مخصصة مع كتابة الأنواع

\n\n

بدلاً من رمي Error عادي، قم بإنشاء تسلسل هرمي للأخطاء المخصصة. سيسمح هذا لـ TypeScript بالتمييز بين أنواع الأخطاء في مرحلة الترجمة.

\n\n
// الفئة الأساسية لجميع أخطاء التطبيق\nclass AppError extends Error {\n  constructor(\n    message: string,\n    public readonly code: string,\n    public readonly statusCode: number = 500\n  ) {\n    super(message);\n    this.name = this.constructor.name;\n  }\n}\n\n// أنواع أخطاء محددة\nclass ValidationError extends AppError {\n  constructor(message: string) {\n    super(message, 'VALIDATION_ERROR', 400);\n  }\n}\n\nclass NotFoundError extends AppError {\n  constructor(resource: string) {\n    super(`${resource} غير موجود`, 'NOT_FOUND', 404);\n  }\n}\n\nclass DatabaseError extends AppError {\n  constructor(message: string) {\n    super(message, 'DB_ERROR', 500);\n  }\n}\n\n// الاستخدام\nfunction findUser(id: string): User {\n  if (!id) throw new ValidationError('المعرف مطلوب');\n  // ... منطق البحث\n  if (!user) throw new NotFoundError('المستخدم');\n  return user;\n}
\n\n

2. حراس الأنواع (Type guards) لمعالجة الأخطاء

\n\n

لمعالجة أنواع مختلفة من الأخطاء بأمان، استخدم حراس الأنواع. هذا هو النمط الأساسي للعمل مع unknown في catch.

\n\n
// حارس النوع لـ AppError\nfunction isAppError(error: unknown): error is AppError {\n  return error instanceof AppError;\n}\n\n// حارس النوع لـ ValidationError\nfunction isValidationError(error: unknown): error is ValidationError {\n  return error instanceof ValidationError;\n}\n\n// معالجة متقدمة\ntry {\n  const user = findUser(userId);\n} catch (error) {\n  if (isValidationError(error)) {\n    // TypeScript يعلم أن error هو ValidationError\n    console.error(`خطأ في التحقق: ${error.message}`);\n    return { status: 400, message: error.message };\n  }\n  \n  if (isAppError(error)) {\n    // error هو AppError\n    console.error(`رمز الخطأ: ${error.code}`);\n    return { status: error.statusCode, message: error.message };\n  }\n  \n  // خطأ غير معروف\n  if (error instanceof Error) {\n    console.error('خطأ غير معروف:', error.message);\n  }\n  \n  return { status: 500, message: 'خطأ داخلي في الخادم' };\n}
\n\n

3. نمط Result (Either monad)

\n\n

هذا بديل للاستثناءات يجعل معالجة الأخطاء صريحة على مستوى الأنواع. بدلاً من رمي خطأ، تقوم الدالة بإرجاع كائن يمكن أن يحتوي إما على نتيجة ناجحة أو خطأ.

\n\n
// تعريف الأنواع لنمط Result\ntype Success<T> = { success: true; data: T };\ntype Failure<E> = { success: false; error: E };\ntype Result<T, E> = Success<T> | Failure<E>;\n\n// دوال مساعدة\nfunction success<T>(data:                

المدونات

توصيات الكتب