> ## Documentation Index
> Fetch the complete documentation index at: https://userepass.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Tratamento de erros

> A hierarquia RepassError, propriedades e como estreitar cada caso no catch.

Toda falha vira uma instância de **`RepassError`** (ou subclasse). Erros da API espelham o [envelope de erro](/docs/convencoes/erros) `{ error: { type, code, message, param? } }`; falhas de transporte (rede/timeout) viram erros próprios.

## Hierarquia

| Classe                      | Quando                                                       | Status    |
| --------------------------- | ------------------------------------------------------------ | --------- |
| `RepassAuthenticationError` | Chave ausente, inválida ou revogada                          | 401       |
| `RepassPermissionError`     | Autenticado, mas sem permissão                               | 403       |
| `RepassNotFoundError`       | Recurso não encontrado                                       | 404       |
| `RepassConflictError`       | Conflito de estado (transição inválida, duplicidade)         | 409       |
| `RepassInvalidRequestError` | Parâmetros inválidos (carrega `param`/`issues`)              | 400       |
| `RepassIdempotencyError`    | Erro de idempotência                                         | 400 / 409 |
| `RepassRateLimitError`      | Limite de requisições atingido                               | 429       |
| `RepassAPIError`            | Erro do servidor ou status inesperado                        | 5xx       |
| `RepassConnectionError`     | Falha de rede/conexão                                        | n/a       |
| `RepassTimeoutError`        | Timeout da requisição (subclasse de `RepassConnectionError`) | n/a       |

Todas herdam de `RepassError`, então `catch (err) { if (err instanceof RepassError) … }` captura qualquer caso.

## Propriedades

Cada erro carrega:

<ParamField path="statusCode" type="number | undefined">
  HTTP status, quando veio de uma resposta da API.
</ParamField>

<ParamField path="type" type="string | undefined">
  `error.type` do envelope (ex.: `invalid_request_error`).
</ParamField>

<ParamField path="code" type="string | undefined">
  `error.code` do envelope (ex.: `resource_not_found`).
</ParamField>

<ParamField path="param" type="string | undefined">
  Campo que originou um erro de validação.
</ParamField>

<ParamField path="issues" type="unknown">
  Detalhes de validação (Zod), em erros 400.
</ParamField>

<ParamField path="requestId" type="string | null">
  Id da requisição (header `x-request-id`), quando a API o emite, informe ao suporte.
</ParamField>

<ParamField path="raw" type="unknown">
  Payload bruto da resposta, para depuração.
</ParamField>

## Estreitando no catch

```ts theme={null}
import {
  Repass,
  RepassError,
  RepassNotFoundError,
  RepassRateLimitError,
  RepassInvalidRequestError,
} from "@repass/sdk";

const repass = new Repass(process.env.REPASS_API_KEY!);

try {
  await repass.programs.retrieve("prog_inexistente");
} catch (err) {
  if (err instanceof RepassNotFoundError) {
    // 404: recurso não existe
  } else if (err instanceof RepassInvalidRequestError) {
    console.error("Campo inválido:", err.param, err.issues);
  } else if (err instanceof RepassRateLimitError) {
    // 429: recue (o SDK já re-tenta automaticamente até maxRetries)
  } else if (err instanceof RepassError) {
    console.error(err.code, err.statusCode, "request:", err.requestId);
  } else {
    throw err;
  }
}
```

<Note>
  Como `404` e `409` compartilham `type: "invalid_request_error"` no envelope, o SDK distingue **pela classe** (`RepassNotFoundError` vs `RepassConflictError`), prefira `instanceof` a comparar `type`.
</Note>

## Erros de transporte

Timeouts e falhas de rede **não** têm `statusCode`. O SDK já re-tenta requisições idempotentes; o que escapa do `maxRetries` é lançado:

```ts theme={null}
import { RepassTimeoutError, RepassConnectionError } from "@repass/sdk";

try {
  await repass.conversions.list({}, { timeout: 2_000 });
} catch (err) {
  if (err instanceof RepassTimeoutError) {
    // a requisição passou de 2s
  } else if (err instanceof RepassConnectionError) {
    // DNS/conexão recusada/rede
  }
}
```
