معالجة الأخطاء في JavaScript: try/catch و async/await والأنماط المتقدمة

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

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

ابدأ الدورة

معالجة متقدمة للأخطاء في JavaScript: من try/catch إلى المعترضات العامة

\n\n

معالجة الأخطاء ليست مجرد "تغليف الكود في try/catch". في تطبيقات الإنتاج الحقيقية على Node.js، الإدارة الصحيحة للاستثناءات تسمح بتجنب انهيار الخادم، وتسجيل المشكلات بشكل صحيح، وإعطاء المستخدم رسائل مفهومة. في هذه المقالة، سنشرح التقنيات المتقدمة لمعالجة الأخطاء في JavaScript التي تتجاوز بناء الجملة الأساسي.

\n\n

1. الغوص العميق في try/catch و finally

\n\n

التركيبة الكلاسيكية try...catch...finally تظل أساس المعالجة المتزامنة. ومع ذلك، على المستوى المتقدم، من المهم فهم الفروق الدقيقة في عملها.

\n\n
function riskyOperation(value) {\n  if (typeof value !== 'number') {\n    throw new TypeError('Argument must be a number');\n  }\n  if (value < 0) {\n    throw new RangeError('Value cannot be negative');\n  }\n  return Math.sqrt(value);\n}\n\ntry {\n  const result = riskyOperation(-4);\n  console.log('Result:', result);\n} catch (error) {\n  if (error instanceof TypeError) {\n    console.error('Type Error:', error.message);\n  } else if (error instanceof RangeError) {\n    console.error('Range Error:', error.message);\n  } else {\n    console.error('Unknown error:', error);\n  }\n} finally {\n  console.log('Cleanup: always executed');\n}
\n\n

النقاط الرئيسية:

\n
    \n
  • كتلة finally تُنفذ دائمًا، حتى لو كان هناك return في try أو catch.
  • \n
  • استخدم فئات الأخطاء المضمنة (TypeError، RangeError، SyntaxError) للتحديد الدقيق.
  • \n
  • لا تعترض الأخطاء التي لا يمكنك معالجتها - اتركها تتصاعد للأعلى.
  • \n
\n\n

2. فئات الأخطاء المخصصة وتوسيع Error

\n\n

للمشاريع الكبيرة، أنواع الأخطاء القياسية غير كافية. إنشاء فئات خاصة بك يسمح بإضافة بيانات وصفية (حالة HTTP، رمز الخطأ، السياق) ويبسط التصفية.

\n\n
class AppError extends Error {\n  constructor(message, statusCode, code) {\n    super(message);\n    this.name = 'AppError';\n    this.statusCode = statusCode;\n    this.code = code;\n    Error.captureStackTrace(this, this.constructor);\n  }\n}\n\nclass ValidationError extends AppError {\n  constructor(message, field) {\n    super(message, 400, 'VALIDATION_ERROR');\n    this.field = field;\n  }\n}\n\nclass DatabaseError extends AppError {\n  constructor(message, query) {\n    super(message, 500, 'DB_ERROR');\n    this.query = query;\n  }\n}\n\n// الاستخدام\ntry {\n  throw new ValidationError('Email is required', 'email');\n} catch (error) {\n  if (error instanceof ValidationError) {\n    console.log(`Field: ${error.field}, Status: ${error.statusCode}`);\n  }\n}
\n\n

لماذا هذا مهم: الأخطاء المخصصة تسمح بمعالجة مركزية لسيناريوهات مختلفة (مثلًا في middleware Express.js) وإرجاع JSON منظم للعميل.

\n\n

3. معالجة الأخطاء في الكود غير المتزامن: async/await و Promise

\n\n

في Node.js، معظم الكود غير متزامن. الأخطاء في Promise و async/await تتطلب نهجًا خاصًا.

\n\n

3.1. معالجة Promise

\n\n
function fetchUserData(userId) {\n  return new Promise((resolve, reject) => {\n    if (userId <= 0) {\n      reject(new RangeError('Invalid user ID'));\n    }\n    // محاكاة طلب لقاعدة البيانات\n    setTimeout(() => resolve({ id: userId, name: 'Alice' }), 100);\n  });\n}\n\nfetchUserData(-1)\n  .then(user => console.log(user))\n  .catch(error => {\n    console.error('Promise rejected:', error.message);\n  })\n  .finally(() => console.log('Cleanup after promise'));
\n\n

3.2. معالجة async/await

\n\n
async function getUserProfile(userId) {\n  try {\n    const user = await fetchUserData(userId);\n    const posts = await fetchUserPosts(user.id                

المدونات

توصيات الكتب