> ## Documentation Index
> Fetch the complete documentation index at: https://docs.youka.io/llms.txt
> Use this file to discover all available pages before exploring further.

# الأخطاء

> التعامل مع YoukaRequestError و YoukaTaskError وإخفاقات قابلة لإعادة المحاولة

يعرض الـ SDK فئتَي أخطاء: `YoukaRequestError` لأخطاء HTTP وإخفاقات التحقق من الصحة، و`YoukaTaskError` للمهام غير المتزامنة التي انتهت بحالة غير ناجحة. كلتاهما تمتدان `Error` وتحملان حقولًا منظَّمة بحيث يمكنك التفريع بناءً على code وstatus وقابلية إعادة المحاولة.

## `YoukaRequestError`

يتم طرحه عند أخطاء HTTP، وإخفاقات التحقق من صحة الطلب، والاستجابات غير السليمة.

```ts theme={null}
import { YoukaRequestError } from "@youka/sdk";

try {
  await client.projects.create(body);
} catch (error) {
  if (error instanceof YoukaRequestError) {
    console.error({
      code: error.code,
      message: error.message,
      status: error.status,
      retryable: error.retryable,
      details: error.details,
    });
  } else {
    throw error;
  }
}
```

### الحقول

<ParamField path="code" type="string">
  رمز خطأ قابل للقراءة آليًا، مثل `INVALID_REQUEST` و`UNAUTHORIZED` و
  `UPLOAD_FAILED`.
</ParamField>

<ParamField path="message" type="string">
  وصف قابل للقراءة البشرية.
</ParamField>

<ParamField path="status" type="number">
  رمز حالة HTTP، إن كان متاحًا.
</ParamField>

<ParamField path="retryable" type="boolean">
  `true` إذا اعتبر الـ SDK أن الخطأ يستحق إعادة المحاولة (حدود المعدّل، أخطاء خادم عابرة، إعادة تشغيل idempotent قيد التقدم).
</ParamField>

<ParamField path="details" type="unknown">
  تفاصيل مقدّمة من الخادم، وعادةً ما تكون قائمة مشكلات Zod لأخطاء التحقق من الصحة.
</ParamField>

### أكواد شائعة

| الرمز                           | السبب                                                                  | قابل لإعادة المحاولة؟ |
| ------------------------------- | ---------------------------------------------------------------------- | --------------------- |
| `INVALID_REQUEST`               | فشل جسم الطلب في التحقق من مخططه قبل إرساله.                           | No                    |
| `UNAUTHORIZED`                  | مفتاح API مفقود أو غير صالح.                                           | No                    |
| `NOT_FOUND`                     | المورد غير موجود أو أنك تفتقر إلى صلاحية الوصول.                       | No                    |
| `CONFLICT`                      | تعارض في الإصدارات (HTTP 409).                                         | Yes                   |
| `TOO_MANY_REQUESTS`             | تم الوصول إلى حد المعدّل (HTTP 429).                                   | Yes                   |
| `INTERNAL_SERVER_ERROR`         | عطل خادم عابر (HTTP 500).                                              | Yes                   |
| `IDEMPOTENT_REPLAY_IN_PROGRESS` | الطلب الأصلي ما يزال قيد التنفيذ تحت نفس مفتاح idempotency (HTTP 202). | Yes                   |
| `INVALID_RESPONSE`              | أعاد الخادم جسمًا لا يطابق المخطط المتوقع.                             | No                    |
| `UPLOAD_FAILED`                 | أعادت عملية رفع Signed URL حالة غير 2xx.                               | Depends on status     |

## `YoukaTaskError`

يتم طرحه من `client.tasks.wait(...)` و`client.projects.wait(...)` و`client.exports.wait(...)` عندما تنتهي المهمة أو عملية التصدير الأساسية بحالة `failed` أو `cancelled` أو `timed-out`.

```ts theme={null}
import { YoukaTaskError } from "@youka/sdk";

try {
  await client.projects.wait(created);
} catch (error) {
  if (error instanceof YoukaTaskError) {
    console.error({
      code: error.code,
      message: error.message,
      status: error.status,
      task: error.task,
    });
  } else {
    throw error;
  }
}
```

### الحقول

<ParamField path="code" type="'TASK_FAILED' | 'TASK_CANCELLED' | 'TASK_TIMED_OUT'">
  يرتبط مباشرةً بالحالة النهائية للمهمة.
</ParamField>

<ParamField path="message" type="string">
  إما رسالة خطأ المهمة المقدّمة من الخادم أو بديل مُنشأ تلقائيًا.
</ParamField>

<ParamField path="status" type="TaskStatus">
  الحالة النهائية للمهمة.
</ParamField>

<ParamField path="task" type="RestTask">
  الحمولة الكاملة للمهمة في لحظة الفشل. مفيدة للتسجيل ورسائل الأخطاء الموجّهة للمستخدم.
</ParamField>

## نمط إعادة المحاولة

ادمج `retryable` مع مفتاح idempotency لبناء حلقة إعادة محاولة آمنة:

```ts theme={null}
import { YoukaRequestError } from "@youka/sdk";

async function createWithRetry<T>(fn: () => Promise<T>, maxAttempts = 3) {
  let lastError: unknown;

  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
    try {
      return await fn();
    } catch (error) {
      lastError = error;
      if (
        error instanceof YoukaRequestError &&
        error.retryable &&
        attempt < maxAttempts
      ) {
        await new Promise((r) => setTimeout(r, 2 ** attempt * 1_000));
        continue;
      }
      throw error;
    }
  }

  throw lastError;
}

await createWithRetry(() =>
  client.projects.create(body, {
    idempotencyKey: "import-2026-04-08-song-001",
  }),
);
```

<Tip>
  احرص دائمًا على إعادة استخدام نفس مفتاح idempotency عبر محاولات الإعادة. وإلا فسيتعامل الخادم مع الإعادة كطلب جديد وقد ينتهي بك الأمر إلى تكرارات.
</Tip>

## الإيقاف والإلغاء

إن إيقاف الطلب (Abort) يطرح `AbortError` القياسي — وليس `YoukaRequestError`. تحقّق منه صراحةً:

```ts theme={null}
try {
  await client.projects.wait(created, { signal: controller.signal });
} catch (error) {
  if (error instanceof Error && error.name === "AbortError") {
    console.log("Cancelled by user");
    return;
  }
  throw error;
}
```

## ما التالي

* [المهام](/ar/sdk/tasks) — مساعدات الانتظار واستطلاع المهام المتقدم
* [المصادقة](/ar/sdk/authentication) — خيارات المُنشئ والإشارات
* [أخطاء API](/ar/api/errors) — نفس الأكواد في HTTP الخام
