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

# Errores

> Gestiona YoukaRequestError, YoukaTaskError y fallos reintentables

El SDK expone dos clases de error: `YoukaRequestError` para fallos HTTP y de validación, y `YoukaTaskError` para tareas asíncronas que terminaron en un estado no exitoso. Ambas extienden `Error` e incluyen campos estructurados para que puedas ramificar según el código, el estado y si es reintentable.

## `YoukaRequestError`

Se lanza para errores HTTP, fallos de validación de la solicitud y respuestas malformadas.

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

### Campos

<ParamField path="code" type="string">
  Código de error legible por máquina, por ejemplo `INVALID_REQUEST`, `UNAUTHORIZED`,
  `UPLOAD_FAILED`.
</ParamField>

<ParamField path="message" type="string">
  Descripción legible por humanos.
</ParamField>

<ParamField path="status" type="number">
  Código de estado HTTP, si está disponible.
</ParamField>

<ParamField path="retryable" type="boolean">
  `true` si el SDK considera que merece la pena reintentar el error (límites de tasa, errores
  transitorios del servidor, repetición idempotente en curso).
</ParamField>

<ParamField path="details" type="unknown">
  Detalles proporcionados por el servidor, normalmente una lista de incidencias de Zod para errores de validación.
</ParamField>

### Códigos comunes

| Código                          | Causa                                                                                   | ¿Reintentable?     |
| ------------------------------- | --------------------------------------------------------------------------------------- | ------------------ |
| `INVALID_REQUEST`               | El cuerpo de la solicitud no pasó la validación del esquema antes de enviarse.          | No                 |
| `UNAUTHORIZED`                  | Falta la clave de API o no es válida.                                                   | No                 |
| `NOT_FOUND`                     | El recurso no existe o no tienes acceso.                                                | No                 |
| `CONFLICT`                      | Conflicto de versión (HTTP 409).                                                        | Sí                 |
| `TOO_MANY_REQUESTS`             | Se alcanzó el límite de tasa (HTTP 429).                                                | Sí                 |
| `INTERNAL_SERVER_ERROR`         | Fallo transitorio del servidor (HTTP 500).                                              | Sí                 |
| `IDEMPOTENT_REPLAY_IN_PROGRESS` | La solicitud original sigue en ejecución con la misma clave de idempotencia (HTTP 202). | Sí                 |
| `INVALID_RESPONSE`              | El servidor devolvió un cuerpo que no coincidía con el esquema esperado.                | No                 |
| `UPLOAD_FAILED`                 | La subida a la URL firmada devolvió un estado no 2xx.                                   | Depende del estado |

## `YoukaTaskError`

Se lanza desde `client.tasks.wait(...)`, `client.projects.wait(...)` y `client.exports.wait(...)` cuando la tarea o exportación subyacente termina en `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;
  }
}
```

### Campos

<ParamField path="code" type="'TASK_FAILED' | 'TASK_CANCELLED' | 'TASK_TIMED_OUT'">
  Se corresponde directamente con el estado terminal de la tarea.
</ParamField>

<ParamField path="message" type="string">
  O bien el mensaje de error de la tarea proporcionado por el servidor, o un fallback generado.
</ParamField>

<ParamField path="status" type="TaskStatus">
  El estado terminal de la tarea.
</ParamField>

<ParamField path="task" type="RestTask">
  La carga útil completa de la tarea en el momento del fallo. Útil para logs y
  mensajes de error orientados al usuario.
</ParamField>

## Patrón de reintento

Combina `retryable` con una clave de idempotencia para construir un bucle de reintento seguro:

```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>
  Reutiliza siempre la misma clave de idempotencia en los reintentos. De lo contrario, el servidor
  trata el reintento como una nueva solicitud y puedes acabar con duplicados.
</Tip>

## Interrupción y cancelación

Interrumpir una solicitud lanza un `AbortError` estándar — no un `YoukaRequestError`. Compruébalo explícitamente:

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

## Qué sigue

* [Tasks](/es/sdk/tasks) — helpers de espera y sondeo avanzado de tareas
* [Authentication](/es/sdk/authentication) — opciones del constructor y señales
* [API errors](/es/api/errors) — los mismos códigos en HTTP en bruto
