
# الأخطاء

تستخدم أخطاء التطبيق غلافًا موحدًا يحتوي على رسالة مقروءة وكود ثابت وفئة. وتضيف أخطاء التحقق تفاصيل على مستوى الحقول، وتُعيد الأخطاء غير المعروفة معرّف طلب للدعم.

```json
{
  "error": "Order not found",
  "code": "ORDER_NOT_FOUND",
  "category": "BUSINESS_LOGIC"
}
```

## الغلاف

| الحقل | النوع | الوصف |
| --- | --- | --- |
| `error` | string | رسالة آمنة لعرضها للمطوّر |
| `code` | string | كود ثابت قابل للقراءة آليًا |
| `category` | string | `VALIDATION` أو `AUTHENTICATION` أو `BUSINESS_LOGIC` أو `SYSTEM` |
| `context` | object | تفاصيل اختيارية؛ تظهر عندما يكون للخطأ تفاصيل إضافية |

يُحذف `context` عندما لا يوجد ما يُضاف. لا تعتمد على تحليل رسالة `error` في منطقك؛ استخدم `code`.

## الفئات

| الفئة | الحالة المعتادة | المعنى |
| --- | --- | --- |
| `VALIDATION` | `400` | جسم الطلب أو الاستعلام أو المسار غير صالح |
| `AUTHENTICATION` | `401`، `403` | بيانات اعتماد مفقودة أو مفتاح غير صالح أو مستخدم غير نشط |
| `BUSINESS_LOGIC` | `404`، `409`، `422` | الطلب صالح لكن المورد أو الحالة الحالية لا تسمح به |
| `SYSTEM` | `500` | خطأ خادم غير متوقع |

## أخطاء التحقق

تُرجع إخفاقات التحقق في Zod الكود `VALIDATION_FAILED` مع عنصر لكل حقل:

```json
{
  "error": "Validation failed",
  "code": "VALIDATION_FAILED",
  "category": "VALIDATION",
  "context": {
    "fields": [
      {
        "path": "items.0.quantity",
        "message": "Expected number, received string",
        "code": "invalid_type"
      }
    ]
  }
}
```

`path` مفصول بنقاط ويمكن أن يشير داخل كائنات ومصفوفات متداخلة. و`code` يأتي من Zod ويفيد في معالجة النماذج عمومًا؛ أما `message` فهو الشرح الموجّه للمطوّر.

## الأخطاء غير المتوقعة

لا تكشف الأخطاء غير المعروفة الرسالة الأصلية أبدًا، لأنها قد تحتوي على SQL أو أسماء جداول أو مسارات ملفات أو أسرار. وتحمل الاستجابة بدلًا من ذلك معرّف طلب:

```json
{
  "error": "An unexpected error occurred",
  "code": "INTERNAL_SERVER_ERROR",
  "category": "SYSTEM",
  "context": {
    "requestId": "3f1c0a9e-6a1b-4a27-8f3e-0d1f2a7c9b11"
  }
}
```

يُسجَّل الخطأ الكامل على الخادم تحت معرّف الطلب نفسه. أرفقه عند الإبلاغ عن مشكلة.

## استجابات خارج الغلاف

بعض الحمايات تجيب قبل تشغيل معالج أخطاء التطبيق وتستخدم جسمًا أصغر:

- **إخفاقات نطاق RBAC** تُرجع `403` مع `{ "error": "Insufficient permissions", "required": "orders:read" }`.
- **إخفاقات مفتاح المتجر** تُرجع `401` مع `{ "error": "Missing store API key" }` أو `{ "error": "Invalid store API key" }`.

اعتبر أي جسم بلا `code` رفضًا على مستوى النقل، لا نتيجة على مستوى منطق العمل.

## أكواد الحالة

| الحالة | المعنى | ما تفعله |
| --- | --- | --- |
| `200` | نجاح | اقرأ الاستجابة |
| `201` | أُنشئ | اقرأ المورد الجديد |
| `400` | فشل التحقق | صحّح الحقول المشار إليها |
| `401` | بيانات اعتماد مفقودة أو غير صالحة | تحقق من المفتاح واسم الترويسة |
| `403` | مستخدم غير نشط أو نطاق مفقود | تحقق من حالة الحساب ونطاقات المستخدم |
| `404` | المورد غير موجود | تحقق من المعرّف أو handle أو slug |
| `409` | تعارض | المورد موجود بالفعل أو تغيّرت الحالة |
| `422` | خرق قاعدة عمل | اقرأ الكود وعدّل الطلب |
| `500` | خطأ خادم غير متوقع | أعد المحاولة بتراجع تدريجي؛ وأبلغ عن معرّف الطلب إذا استمر |

## إرشادات إعادة المحاولة

- **لا تُعد المحاولة** مع `400` أو `401` أو `403` أو `404` أو `422` بالطلب نفسه. غيّر الطلب أو بيانات الاعتماد أولًا.
- **أعد المحاولة مع `500`** بتراجع أُسّي مع عشوائية. واحتفظ بمعرّف الطلب من الاستجابة.
- **الإنشاءات ليست متكررة بأمان افتراضيًا.** إعادة محاولة الإنشاء قد تنشئ موردًا ثانيًا. قبل إعادة المحاولة، اقرأ المورد مرة أخرى عبر مفتاح طبيعي مثل رقم طلب أو handle أو رقم هاتف.
- **Webhooks شركات التوصيل متكررة بأمان عند الاستلام.** تزيل صندوق الوارد التكرار بحسب معرّف الحدث من المزوّد، لذا لا تعالج إعادة محاولة شركة التوصيل الحدث نفسه مرتين.

## العثور على كود

يعرض [مرجع API](/api) غلاف `ErrorResponse` الذي تستخدمه كل عملية. الأكواد معرّفات ثابتة مجمّعة حسب المجال: التحقق والمصادقة والطلبات والمنتجات والتوصيل والمراجعات وصفحات الهبوط وإدارة MCP وأخطاء النظام.
