> ## 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.

# Erreurs

> Gérer YoukaRequestError, YoukaTaskError et les échecs pouvant être retentés

Le SDK expose deux classes d’erreurs : `YoukaRequestError` pour les erreurs HTTP et de validation, et `YoukaTaskError` pour les tâches asynchrones qui se terminent dans un état non réussi. Les deux étendent `Error` et embarquent des champs structurés afin que vous puissiez brancher sur le code, le statut et la possibilité de retenter.

## `YoukaRequestError`

Levée pour les erreurs HTTP, les échecs de validation de requête et les réponses malformées.

```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;
  }
}
```

### Champs

<ParamField path="code" type="string">
  Code d’erreur lisible par machine, par exemple `INVALID_REQUEST`, `UNAUTHORIZED`,
  `UPLOAD_FAILED`.
</ParamField>

<ParamField path="message" type="string">
  Description lisible par l’humain.
</ParamField>

<ParamField path="status" type="number">
  Code de statut HTTP, si disponible.
</ParamField>

<ParamField path="retryable" type="boolean">
  `true` si le SDK considère que l’erreur mérite d’être retentée (limites de débit, erreurs
  serveur transitoires, relecture idempotente en cours).
</ParamField>

<ParamField path="details" type="unknown">
  Détails fournis par le serveur, généralement une liste d’issues Zod pour les erreurs de validation.
</ParamField>

### Codes courants

| Code                            | Cause                                                                                 | Retentable ?     |
| ------------------------------- | ------------------------------------------------------------------------------------- | ---------------- |
| `INVALID_REQUEST`               | Le corps de la requête n’a pas passé la validation du schéma avant l’envoi.           | Non              |
| `UNAUTHORIZED`                  | Clé API manquante ou invalide.                                                        | Non              |
| `NOT_FOUND`                     | La ressource n’existe pas ou vous n’y avez pas accès.                                 | Non              |
| `CONFLICT`                      | Conflit de version (HTTP 409).                                                        | Oui              |
| `TOO_MANY_REQUESTS`             | Limite de débit atteinte (HTTP 429).                                                  | Oui              |
| `INTERNAL_SERVER_ERROR`         | Panne serveur transitoire (HTTP 500).                                                 | Oui              |
| `IDEMPOTENT_REPLAY_IN_PROGRESS` | La requête d’origine est toujours en cours avec la même clé d’idempotence (HTTP 202). | Oui              |
| `INVALID_RESPONSE`              | Le serveur a renvoyé un corps qui ne correspondait pas au schéma attendu.             | Non              |
| `UPLOAD_FAILED`                 | L’upload via l’URL signée a renvoyé un statut non-2xx.                                | Dépend du statut |

## `YoukaTaskError`

Levée depuis `client.tasks.wait(...)`, `client.projects.wait(...)` et `client.exports.wait(...)` lorsque la tâche ou l’export sous-jacent se termine en `failed`, `cancelled` ou `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;
  }
}
```

### Champs

<ParamField path="code" type="'TASK_FAILED' | 'TASK_CANCELLED' | 'TASK_TIMED_OUT'">
  Correspond directement au statut terminal de la tâche.
</ParamField>

<ParamField path="message" type="string">
  Soit le message d’erreur de la tâche fourni par le serveur, soit un message de repli généré.
</ParamField>

<ParamField path="status" type="TaskStatus">
  Le statut terminal de la tâche.
</ParamField>

<ParamField path="task" type="RestTask">
  La charge utile complète de la tâche au moment de l’échec. Utile pour la journalisation et
  les messages d’erreur destinés à l’utilisateur.
</ParamField>

## Modèle de retry

Combinez `retryable` avec une clé d’idempotence pour construire une boucle de retry sûre :

```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>
  Réutilisez toujours la même clé d’idempotence lors des retries. Sinon le serveur
  traite le retry comme une nouvelle requête et vous risquez d’obtenir des doublons.
</Tip>

## Abandon et annulation

L’abandon d’une requête lève un `AbortError` standard — pas un `YoukaRequestError`. Vérifiez-le explicitement :

```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;
}
```

## Et ensuite

* [Tâches](/fr/sdk/tasks) — helpers d’attente et polling avancé des tâches
* [Authentification](/fr/sdk/authentication) — options du constructeur et signaux
* [Erreurs d’API](/fr/api/errors) — les mêmes codes en HTTP brut
