# Erros

> VimineError — um único tipo de erro para tudo o que a API e o SDK podem recusar, com um código estável.

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

```js
import { VimineError } from '@vimine/sdk';   // também de /server
```

Tudo o que dá errado chega como um `VimineError`, uma subclasse de `Error`. O **`code`** é o identificador
estável em que basear as suas decisões: o `code` de um documento problem+json (RFC 9457), o `error` de uma resposta
OAuth, ou um dos códigos próprios do SDK.

## Propriedades

| | Tipo | |
|---|---|---|
| `code` | `string` | o código estável |
| `message` | `string` | o `detail` ou o `title` do problema, ou `error_description` |
| `status` | `number \| null` | o status HTTP, `null` para os erros locais |
| `requestId` | `string \| null` | o `request_id` da resposta: informe-o nos relatos de problema |
| `detail` | `string \| null` | o `detail` do problema |
| `errors` | `FieldError[]` — `{ field?, code?, message? }` | os detalhes de `validation_failed` e de `identification_required`; uma entrada `codicefiscale_mismatch` também traz `mismatches`, `hints` e `confirmable` ([guia](https://developers.vimine.network/pt/guides/members-without-cf/#um-código-que-não-confere-e-a-confirmação)) |
| `cause` | `unknown` | o erro de origem (`network`, `framed`) |
| `isAuthError` | `boolean` | `true` para "a sessão acabou: entre de novo" (401, `invalid_token`, `token_expired`, `missing_token`, `invalid_grant`, `not_signed_in`) |

## Os códigos do SDK

| `code` | Quando |
|---|---|
| `invalid_options` | construtor sem `clientId`, `redirectUri` ou `clientSecret` |
| `network` | a requisição não chegou à API (`cause` traz o erro original) |
| `not_signed_in` | nenhuma sessão, ou nenhum refresh token, para uma chamada autenticada |
| `no_flow` | um retorno sem um login iniciado neste navegador (storage vazio ou expirado) |
| `state_mismatch` | o retorno não corresponde ao login que foi iniciado |
| `framed` | `signIn()` a partir de um frame de outra origem |
| `http_<status>` | uma resposta de erro sem um corpo JSON reconhecível |

Os códigos da **API** (`insufficient_scope`, `not_found`, `validation_failed`, `statuto_required`, `rate_limited`,
…) e os do **OAuth** (`invalid_grant`, `access_denied`, `unauthorized_client`, …) estão em
[Permissões, erros e limites](https://developers.vimine.network/pt/guides/scopes-and-errors/).

## Como tratá-los

```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(`Há uma versão mais recente em 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);
    }
}
```
