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

# Tratamento de Erros

> Guia de tratamento de erros e resiliência na integração

# Tratamento de Erros

Guia de como tratar erros retornados pelas APIs Zipdin e implementar resiliência na sua integração.

## Formato Padrão de Erro

Todas as APIs retornam erros no mesmo formato JSON:

```json theme={null}
{
  "error": "CODIGO_DO_ERRO",
  "message": "Descrição legível para humanos",
  "details": {
    "campo_adicional": "informação contextual"
  }
}
```

## Respostas de Erro Padrão

Todas as APIs seguem o mesmo formato de erro:

```json theme={null}
{
  "error": "CODIGO_ERRO",
  "message": "Descrição legível do erro",
  "details": {}
}
```

<AccordionGroup>
  <Accordion title="400 - Bad Request" icon="circle-exclamation">
    Parâmetros inválidos ou ausentes na requisição.

    ```json theme={null}
    {
      "error": "VALIDATION_ERROR",
      "message": "Campo obrigatório ausente",
      "details": {
        "field": "nu_cpf",
        "reason": "required"
      }
    }
    ```
  </Accordion>

  <Accordion title="401 - Unauthorized" icon="lock">
    Token ausente, expirado ou inválido.

    ```json theme={null}
    {
      "error": "INVALID_TOKEN",
      "message": "Token expirado ou inválido",
      "details": {}
    }
    ```

    **Solução:** Gere um novo token via `/oauth/token`.
  </Accordion>

  <Accordion title="403 - Forbidden" icon="ban">
    Usuário autenticado mas sem permissão para o recurso.

    ```json theme={null}
    {
      "error": "INSUFFICIENT_SCOPE",
      "message": "Permissão insuficiente para esta operação",
      "details": {
        "required_scope": "admin"
      }
    }
    ```
  </Accordion>

  <Accordion title="404 - Not Found" icon="magnifying-glass">
    Recurso não encontrado.

    ```json theme={null}
    {
      "error": "RESOURCE_NOT_FOUND",
      "message": "Proposta não encontrada",
      "details": {
        "resource": "proposta",
        "id": "123456"
      }
    }
    ```
  </Accordion>

  <Accordion title="422 - Unprocessable Entity" icon="triangle-exclamation">
    Dados válidos sintaticamente, mas que violam regras de negócio.

    ```json theme={null}
    {
      "error": "BUSINESS_RULE_VIOLATION",
      "message": "Margem insuficiente para o valor solicitado",
      "details": {
        "margem_disponivel": 350.00,
        "parcela_solicitada": 500.00
      }
    }
    ```
  </Accordion>

  <Accordion title="429 - Too Many Requests" icon="gauge-high">
    Limite de requisições excedido.

    ```json theme={null}
    {
      "error": "RATE_LIMITED",
      "message": "Limite de requisições excedido. Tente novamente em 60s",
      "details": {
        "retry_after": 60
      }
    }
    ```

    **Solução:** Respeite o header `Retry-After` na resposta.
  </Accordion>

  <Accordion title="500 - Internal Server Error" icon="server">
    Erro inesperado no servidor.

    ```json theme={null}
    {
      "error": "INTERNAL_ERROR",
      "message": "Erro interno. Contate o suporte com o correlation_id",
      "details": {
        "correlation_id": "abc-123-def-456"
      }
    }
    ```

    **Solução:** Reporte ao suporte informando o `correlation_id`.
  </Accordion>
</AccordionGroup>

## Estratégia de Retry

### Erros Retriáveis

| HTTP Status | Deve fazer retry? | Estratégia                     |
| :---------: | :---------------: | ------------------------------ |
|     408     |        Sim        | Retry imediato (1x)            |
|     429     |        Sim        | Respeitar `Retry-After` header |
|     500     |        Sim        | Backoff exponencial            |
| 502/503/504 |        Sim        | Backoff exponencial            |
|     400     |        Não        | Corrigir o request             |
|     401     |      Parcial      | Renovar token e retry 1x       |
|     403     |        Não        | Verificar permissões           |
|     404     |        Não        | Recurso não existe             |
|     422     |        Não        | Regra de negócio violada       |

### Backoff Exponencial

```python theme={null}
import time
import requests

def request_with_retry(url, headers, max_retries=3):
    for attempt in range(max_retries):
        response = requests.get(url, headers=headers)
        
        if response.status_code < 500:
            return response
        
        wait_time = (2 ** attempt) + random.uniform(0, 1)
        time.sleep(wait_time)
    
    raise Exception(f"Falha após {max_retries} tentativas")
```

## Correlation ID

Toda resposta inclui um header `X-Correlation-Id`. Use-o ao reportar problemas ao suporte:

```
X-Correlation-Id: req_a1b2c3d4-e5f6-7890-abcd-ef1234567890
```

<Tip>
  Registre o `X-Correlation-Id` nos seus logs para facilitar
  troubleshooting em conjunto com o time Zipdin.
</Tip>

## Timeout Recomendado

| Tipo de Operação     | Timeout Recomendado |
| -------------------- | :-----------------: |
| Consultas (GET)      |     10 segundos     |
| Criação/Atualização  |     30 segundos     |
| Averbação            |     60 segundos     |
| Upload de documentos |     120 segundos    |

## Circuit Breaker

Para integrações de alto volume, implemente circuit breaker:

```javascript theme={null}
// Exemplo com padrão circuit breaker
const circuitBreaker = {
  failures: 0,
  threshold: 5,
  timeout: 30000, // 30s em estado "open"
  lastFailure: null,
  
  async call(fn) {
    if (this.isOpen()) {
      throw new Error("Circuit breaker open - API indisponível");
    }
    try {
      const result = await fn();
      this.reset();
      return result;
    } catch (err) {
      this.recordFailure();
      throw err;
    }
  }
};
```
