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

# Errori

> Gestisci YoukaRequestError, YoukaTaskError e i fallimenti ritentabili

L’SDK espone due classi di errore: `YoukaRequestError` per errori HTTP e di validazione, e `YoukaTaskError` per task asincroni terminati in uno stato non riuscito. Entrambe estendono `Error` e includono campi strutturati così puoi diramare la logica in base a codice, stato e possibilità di retry.

## `YoukaRequestError`

Generato per errori HTTP, errori di validazione della richiesta e risposte malformate.

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

### Campi

<ParamField path="code" type="string">
  Codice di errore leggibile dalla macchina, ad esempio `INVALID_REQUEST`, `UNAUTHORIZED`,
  `UPLOAD_FAILED`.
</ParamField>

<ParamField path="message" type="string">
  Descrizione leggibile dall’uomo.
</ParamField>

<ParamField path="status" type="number">
  Codice di stato HTTP, se disponibile.
</ParamField>

<ParamField path="retryable" type="boolean">
  `true` se l’SDK considera l’errore meritevole di un retry (rate limit, errori
  transitori del server, rigioco idempotente in corso).
</ParamField>

<ParamField path="details" type="unknown">
  Dettagli forniti dal server, tipicamente un elenco di issue Zod per errori di validazione.
</ParamField>

### Codici comuni

| Codice                          | Causa                                                                                         | Ritentabile?         |
| ------------------------------- | --------------------------------------------------------------------------------------------- | -------------------- |
| `INVALID_REQUEST`               | Il body della richiesta non ha superato la validazione dello schema prima dell’invio.         | No                   |
| `UNAUTHORIZED`                  | Chiave API mancante o non valida.                                                             | No                   |
| `NOT_FOUND`                     | La risorsa non esiste o non hai accesso.                                                      | No                   |
| `CONFLICT`                      | Conflitto di versione (HTTP 409).                                                             | Sì                   |
| `TOO_MANY_REQUESTS`             | Raggiunto il limite di richieste (HTTP 429).                                                  | Sì                   |
| `INTERNAL_SERVER_ERROR`         | Errore transitorio del server (HTTP 500).                                                     | Sì                   |
| `IDEMPOTENT_REPLAY_IN_PROGRESS` | La richiesta originale è ancora in esecuzione con la stessa chiave di idempotenza (HTTP 202). | Sì                   |
| `INVALID_RESPONSE`              | Il server ha restituito un body che non corrispondeva allo schema atteso.                     | No                   |
| `UPLOAD_FAILED`                 | L’upload su Signed URL ha restituito un non-2xx.                                              | Dipende dallo status |

## `YoukaTaskError`

Generato da `client.tasks.wait(...)`, `client.projects.wait(...)` e `client.exports.wait(...)` quando il task o l’export sottostante termina in `failed`, `cancelled` o `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;
  }
}
```

### Campi

<ParamField path="code" type="'TASK_FAILED' | 'TASK_CANCELLED' | 'TASK_TIMED_OUT'">
  Corrisponde direttamente allo stato finale del task.
</ParamField>

<ParamField path="message" type="string">
  Il messaggio di errore del task fornito dal server oppure un fallback generato.
</ParamField>

<ParamField path="status" type="TaskStatus">
  Lo stato finale del task.
</ParamField>

<ParamField path="task" type="RestTask">
  Il payload completo del task al momento del fallimento. Utile per logging e
  messaggi di errore rivolti all’utente.
</ParamField>

## Pattern di retry

Combina `retryable` con una chiave di idempotenza per costruire un ciclo di retry sicuro:

```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>
  Riutilizza sempre la stessa chiave di idempotenza tra i retry. Altrimenti il server
  tratta il retry come una nuova richiesta e potresti finire con duplicati.
</Tip>

## Interruzione e cancellazione

L’interruzione di una richiesta genera un `AbortError` standard — non un `YoukaRequestError`. Verificalo esplicitamente:

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

## Cosa fare dopo

* [Tasks](/it/sdk/tasks) — helper di attesa e polling avanzato dei task
* [Authentication](/it/sdk/authentication) — opzioni del costruttore e signal
* [API errors](/it/api/errors) — gli stessi codici in HTTP raw
