# Errores

> VimineError — un único tipo de error para todo lo que la API y el SDK pueden rechazar, con un código estable.

URL: https://developers.vimine.network/es/sdk/errors/

```js
import { VimineError } from '@vimine/sdk';   // también desde /server
```

Todo lo que sale mal llega como un `VimineError`, una subclase de `Error`. **`code`** es el identificador estable
sobre el que ramificar: el `code` de un documento problem+json (RFC 9457), el `error` de una respuesta OAuth o uno de
los códigos propios del SDK.

## Propiedades

| | Tipo | |
|---|---|---|
| `code` | `string` | el código estable |
| `message` | `string` | el `detail` o el `title` del problema, o `error_description` |
| `status` | `number \| null` | el estado HTTP, `null` para los errores locales |
| `requestId` | `string \| null` | el `request_id` de la respuesta: indícalo en los informes |
| `detail` | `string \| null` | el `detail` del problema |
| `errors` | `FieldError[]` — `{ field?, code?, message? }` | los detalles de `validation_failed` y de `identification_required`; una entrada `codicefiscale_mismatch` lleva además `mismatches`, `hints` y `confirmable` ([guía](https://developers.vimine.network/es/guides/members-without-cf/#un-código-que-no-coincide-y-la-confirmación)) |
| `cause` | `unknown` | el error de origen (`network`, `framed`) |
| `isAuthError` | `boolean` | `true` para «la sesión ya no existe: vuelve a iniciar sesión» (401, `invalid_token`, `token_expired`, `missing_token`, `invalid_grant`, `not_signed_in`) |

## Los códigos del SDK

| `code` | Cuándo |
|---|---|
| `invalid_options` | constructor sin `clientId`, `redirectUri` o `clientSecret` |
| `network` | la petición no ha llegado a la API (`cause` lleva el error original) |
| `not_signed_in` | sin sesión, o sin refresh token, para una llamada autenticada |
| `no_flow` | una vuelta sin un inicio de sesión empezado desde este navegador (almacenamiento vacío o caducado) |
| `state_mismatch` | la vuelta no corresponde al inicio de sesión que se empezó |
| `framed` | `signIn()` desde un marco de otro origen |
| `http_<status>` | una respuesta de error sin un cuerpo JSON reconocible |

Los códigos de la **API** (`insufficient_scope`, `not_found`, `validation_failed`, `statuto_required`,
`rate_limited`, …) y los de **OAuth** (`invalid_grant`, `access_denied`, `unauthorized_client`, …) están en
[Permisos, errores y límites](https://developers.vimine.network/es/guides/scopes-and-errors/).

## Cómo gestionarlos

```js
import { VimineError } from '@vimine/sdk';

try {
    await vimine.membership.acceptStatuto({ version });
} catch (err) {
    if (!(err instanceof VimineError)) throw err;
    if (err.isAuthError) return vimine.signIn({ returnTo: location.pathname });
    switch (err.code) {
        case 'statuto_outdated':  return alert(`Hay una versión más reciente en vigor: ${err.detail}`);
        case 'insufficient_scope': return vimine.signIn({ scopes: ['statuto:accept'], prompt: 'consent' });
        case 'rate_limited':      return setTimeout(retry, 5000);
        default:                  console.error(err.code, err.requestId);
    }
}
```
