---
title: "كود المسار السعيد فقط"
type: "ai-smell"
slug: "happy-path-only"
url: "http://localhost:3000/ar/ai-smells/happy-path-only.md"
category: "الصحة"
description: "يميل مساعدو الذكاء الاصطناعي إلى توليد كود يتعامل فقط مع الحالة الناجحة والسليمة — مع تخطي التحقق من صحة المدخلات، ومعالجة الأخطاء، وفحوصات القيم الفارغة/null، وحالات الحافة — بحيث يعمل الكود في العرض التوضيحي وينهار في الإنتاج الفعلي."
---
# كود المسار السعيد فقط

> يميل مساعدو الذكاء الاصطناعي إلى توليد كود يتعامل فقط مع الحالة الناجحة والسليمة — مع تخطي التحقق من صحة المدخلات، ومعالجة الأخطاء، وفحوصات القيم الفارغة/null، وحالات الحافة — بحيث يعمل الكود في العرض التوضيحي وينهار في الإنتاج الفعلي.

## Signs and Symptoms

يكتشف المراجع كود المسار السعيد فقط عندما يفترض كل سطر أن السطر السابق قد نجح: لا يتم فحص استدعاءات الشبكة لمعرفة الحالات غير الناجحة، ولا يتم تغليف `JSON.parse`/`await res.json()` في كتل معالجة، ويتم إلغاء الإشارة إلى الحقول القابلة للقيمة null مباشرة، ويتم فهرسة المصفوفات دون فحص طولها، وتتدفق المدخلات الخارجية مباشرة إلى المنطق دون أي تحقق من صحتها. عادةً ما يكون هناك مسار إرجاع واحد بالضبط ولا توجد جمل `throw`، ولا جمل حماية، ولا كتل `catch` (أو توجد كتلة `catch` فارغة أو تحتوي على `console.log` فقط).

```ts
// مولد بالذكاء الاصطناعي: سيناريو النجاح فقط هو الموجود
async function getUserCity(userId) {
  const res = await fetch(`/api/users/${userId}`);
  const user = await res.json();
  return user.address.city.toUpperCase();
}

```

حالات الفشل الغائبة بصمت: لم يتم فحص `res.ok` (تعديل 404/500 يعيد متناً للخطأ قد يرفضه `.json()`)، وقد يكون `user` عبارة عن كائن فارغ `{}`، وقد يكون حقل `address` عبارة عن `null`، وحقل `city` قد يكون `undefined` ← خطأ `Cannot read properties of undefined`. الدالة "تعمل" مقابل نموذج وهمي ناجح وتفشل أمام الواقع.

العلامات المميزة في ملف الفروقات (diff):

* دالة `async` جديدة بدون كتل `try`/`catch` ودون استدعاء `.catch()` للوعد (promise).
* سلاسل وصول مباشرة للخصائص (`a.b.c.d`) على البيانات التي عبرت حدود الثقة/المدخلات.
* استخدام غير مفحوص لـ `arr[0]`، أو `find(...)!`، أو تحويلات الأنواع بـ `as`، أو تأكيدات عدم القيمة null (`!`) كبديل للمعالجة الحقيقية.
* وجود تعليقات مثل `// TODO: handle errors` أو كتلة فارغة `catch (e) {}` كعنصر نائب مؤقت.
* وصف طلب السحب (PR) يقول "يعالج X" ولكن فرع نجاح X فقط هو المطبق.

## Reasons for the Problem

**لماذا تنتجها النماذج؟**

* **احتمالية الرمز التالي تفضل التدفق النموذجي.** التكملة الأكثر احتمالاً بعد `const user = await res.json()` هي `return user.something` — وليس فحص حالة الاستجابة. معالجة الأخطاء هي عبارة عن كود جاهز عالي التباين يختلف من قاعدة كود لأخرى، وبالتالي فهو "مفاجئ" إحصائياً للنموذج ويتم حذفه.
* **بيانات التدريب منحازة للمسار السعيد.** تحذف الدروس البرمجية، ولقطات ملفات README، ومقالات المدونات، وإجابات Stack Overflow المقبولة عمليات التحقق ومعالجة الأخطاء للاختصار ("تم حذف معالجة الأخطاء للتوضيح"). لقد تعلم النموذج من نصوص أزالت عمداً الكود الذي تريده أنت وتطالب به.
* **التملق / مكافأة المظهر النظيف.** تتم مكافأة المساعدين الذين تم ضبطهم عبر RLHF على الإجابات الموجزة والاستجابة المباشرة. يبدو الكود الدفاعي وكأنه ضوضاء، لذلك يقوم النموذج بالتحسين لإنتاج مقطع كود أنيق يبدو وكأنه يجيب على الأمر الموجه.
* **غياب سياق المستودع.** لا يعرف النموذج أن لديك نوع `AppError`، أو مغلف `Result<T>`، أو مخطط `zod`، أو اصطلاحاً لتسجيل الأخطاء، وبالتالي لا يمكنه إعادة استخدامها — ويلجأ افتراضياً إلى عدم معالجة شيء بدلاً من تخمين اصطلاحاتك.
* **النزعات السلوكية الموثقة.** يصنف تحليل Ox Security لأكثر من 300 مستودع _تجنب إعادة الهيكلة_ و_الهوس بالحلول المألوفة_ ضمن أهم الأنماط المضادة للذكاء الاصطناعي — حيث يصدر النموذج كوداً يعمل للمهمة الفورية ولا يقويه أبداً. تصنف ورقة arXiv 2509.20491 روائح الكود الخاصة بالذكاء الاصطناعي حول _الفشل الصامت_؛ وتجد ورقة arXiv 2510.03029 روائح تطبيق مرتفعة مثل _كتلة catch الفارغة_ في مخرجات نماذج اللغة الكبيرة.

**لماذا يسبب ضرراً؟**

* **الصحة:** ينهار الكود عند مواجهة قيم `null`، أو مصفوفات فارغة، أو فترات انتهاء الصلاحية، أو الاستجابات غير الناجحة (غير 200) — وهي بالضبط المدخلات التي لا تظهر في اختبار يدوي سريع.
* **الأمان:** يثق المسار السعيد بالمدخلات بشكل ضمني. تخطي التحقق من صحة المدخلات عند الحدود هو كيفية تسلل ثغرات الحقن (injection)، واجتياز المسارات (path traversal)، وتلويث النموذج الأولي (prototype pollution). يصيغ تقرير Ox هذا كـ كود "غير آمن بسبب الغباء"، يتم شحنه بسرعة دون إعمال العقل أو الحكم البرمجي.
* **عبء المراجعة وتصحيح الأخطاء:** في استطلاع مطوري Stack Overflow لعام 2025، يذكر 66% من المطورين أن "حلول الذكاء الاصطناعي شبه الصحيحة ولكن ليس تماماً" هي أكبر إحباط لديهم، ويقول 45% منهم إن تصحيح الكود المولد بالذكاء الاصطناعي يستغرق وقتاً _أطول_. كود المسار السعيد هو النموذج المثالي لـ "شبه الصحيح" — فهو يقرأ بسلاسة ولكنه يفشل في الإنتاج الفعلي.
* **تراكم الديون التقنية:** نظراً لأن النموذج لا يعيد الهيكلة أو يعيد استخدام دوال الأخطاء المساعدة الحالية، فإن كل دالة مسار سعيد تمثل كتلة جديدة أحادية الاستخدام. تُظهر بيانات GitClear لعام 2025 النمط الأوسع — حيث ارتفعت السطور المنسوخة/الملصقة من 8.3% (2021) إلى 12.3% (2024)، ونمت الكتل المكررة المكونة من 5 سطور أو أكثر بمعدل \~8 أضعاف في عام 2024، بينما انخفضت إعادة الهيكلة (السطور المنقولة) من \~25% إلى أقل من 10%. ويتم تثبيت معالجة الأخطاء المفقودة لاحقاً، وتتكرر في كل موضع استدعاء، ولا تكون مركزية أبداً.

## Treatment

**تكتيكات المراجعة وصياغة الأوامر**

* **اجعل النموذج يعدد حالات الفشل أولاً.** وجّه النموذج: "قبل كتابة الكود، عدد حالات الفشل لهذه الدالة (المدخلات السيئة، خطأ الشبكة، الاستجابات غير الناجحة، الاستجابة الفارغة/المشوهة، الحقول المفقودة، التزامن). ثم قم بتطبيق المعالجة لكل منها". إن فرض خطوة التعداد يواجه ميل الرمز التالي لتخطيها.
* **أشر إلى الاصطلاحات التي يجب إعادة استخدامها.** "استخدم نوع `AppError`/`Result` الحالي من `lib/errors.ts` والمسجل `logger` من `lib/log.ts`؛ وتحقق من صحة الاستجابة باستخدام مخطط `zod` في `schemas/user.ts`". هذا يحول غياب المعالجة إلى إعادة استخدام بدلاً من كتلة كود مخصصة (ويتجنب _الكود المكرر_).
* **اطلب تشغيل حواجز الحماية.** "شغّل `eslint` و `tsc --noEmit` وأصلح كل تحذير، بما في ذلك `@typescript-eslint/no-floating-promises`". يؤدي التحقق من الأنواع مع تشغيل `strictNullChecks` إلى تحويل إلغاء إشارة null الصامتة إلى أخطاء تجميع يتعين على النموذج معالجتها.
* **اطلب الاختبارات السلبية.** اطلب اختبارات وحدة تغطي المدخلات الفارغة/الملغاة/الخاطئة، وليس فقط حالة النجاح — فغياب هذه الاختبارات هو نفسه الرائحة الفاضحة.

**إعادة هيكلة الكود**

أضف التحقق من الصحة عند الحدود وجمل الحماية، واجعل المعالجة مركزية. الحركات المعتمدة: **تقديم جملة حماية (Introduce Guard Clause)** (إطلاق `throw` مبكر عند حالة غير صالحة)، و**تقديم تأكيد / التحقق عند الحدود (Introduce Assertion / boundary validation)** (التنقية لا التحقق عند حواف الإدخال/الإخراج)، و**تقديم حالة خاصة / كائن null (Introduce Special Case / Null Object)** (استخدام `?? "UNKNOWN"` بدلاً من الانهيار).

```ts
// بعد: حالات الفشل هي مواطنون من الدرجة الأولى
async function getUserCity(userId: string): Promise<string> {
  if (!userId) throw new InvalidArgumentError("userId required");   // جملة حماية (guard clause)

  const res = await fetch(`/api/users/${encodeURIComponent(userId)}`);
  if (!res.ok) throw new ApiError(`user fetch failed: ${res.status}`);

  const user = UserSchema.parse(await res.json());                  // التحقق من الصحة عند الحدود
  return user.address?.city?.toUpperCase() ?? "UNKNOWN";           // معالجة الفجوة كحالة خاصة
}

```

إذا بدأ نمط try/validate/log يتكرر عبر مواقع الاستدعاء، فاستخدم **استخراج الدالة (Extract Function)** في دالة مساعدة مشتركة `fetchJson<T>(url, schema)` بحيث تعيش معالجة الأخطاء في مكان واحد بدلاً من نسخها ولصقها (فخ تكرار GitClear).

## Detected by

- **typescript-eslint** `@typescript-eslint/no-floating-promises` — تمييز الوعود (promises) التي لا يتم التعامل مع مسار رفضها أبداً (بدون await/catch) — وهي علامة شائعة للمسار السعيد في الاستدعاءات غير المتزامنة. (https://typescript-eslint.io/rules/no-floating-promises/)
- **ESLint** `no-empty` — تمييز الكتل الفارغة بما في ذلك كتل catch الفارغة — وهي بمثابة 'معالجة الأخطاء' المؤقتة التي يتركها النموذج خلفه. (https://eslint.org/docs/latest/rules/no-empty)
- **SonarSource (JS/TS)** `javascript:S2486` — يجب عدم تجاهل الاستثناءات — تمييز الأخطاء التي تم التقاطها وتجاهلها بصمت، وهي الممارسة القريبة لعدم المعالجة على الإطلاق. (https://rules.sonarsource.com/javascript/RSPEC-2486/)
