Erros & Status HTTP
Tabela de codigos de erro
| Codigo | Significado | Causas comuns |
|---|---|---|
400 |
Bad Request | Campos obrigatorios ausentes, tipos invalidos |
401 |
Unauthorized | Token ausente, invalido ou expirado |
403 |
Forbidden | Role insuficiente para o endpoint |
404 |
Not Found | Recurso nao existe ou nao pertence ao usuario |
422 |
Unprocessable Entity | Transicao de status invalida, saldo insuficiente |
502 |
Bad Gateway | Servico externo falhou (ASAAS ou OpenRouteService) |
Formato padrao de resposta de erro
Todos os erros seguem o schema:
Para erros de validacao (400), o FastAPI retorna o formato Pydantic:
{
"detail": [
{
"type": "missing",
"loc": ["body", "origin_address"],
"msg": "Field required",
"input": {}
}
]
}
Exemplos de erro por codigo
401 — Token expirado
Solucao: Refaca o login ou use o refresh_token para obter um novo access_token. Ver Autenticacao.
403 — Role insuficiente
Solucao: Verifique se esta usando credenciais com a role correta para o endpoint.
404 — Entrega nao encontrada
422 — Transicao de status invalida
422 — Saldo insuficiente
502 — Servico externo indisponivel
Tratamento de erros em codigo
import requests
import time
def call_with_retry(url: str, headers: dict, max_retries: int = 3) -> dict:
"""Chamada com backoff exponencial para erros 502."""
for attempt in range(max_retries):
resp = requests.get(url, headers=headers)
if resp.status_code == 200:
return resp.json()
if resp.status_code == 401:
raise Exception("Token invalido ou expirado — refaca o login")
if resp.status_code == 403:
raise Exception("Acesso negado — verifique sua role")
if resp.status_code == 404:
raise Exception(f"Recurso nao encontrado: {url}")
if resp.status_code == 422:
detail = resp.json().get("detail", "Erro de validacao")
raise Exception(f"Dado invalido: {detail}")
if resp.status_code == 502:
wait = 2 ** attempt # 1s, 2s, 4s
print(f"Servico externo falhou, aguardando {wait}s (tentativa {attempt + 1}/{max_retries})")
time.sleep(wait)
continue
resp.raise_for_status()
raise Exception(f"Falhou apos {max_retries} tentativas")
async function callWithRetry(url, headers, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const resp = await fetch(url, { headers });
if (resp.ok) return resp.json();
const body = await resp.json().catch(() => ({}));
const detail = body.detail ?? resp.statusText;
if (resp.status === 401) throw new Error("Token invalido ou expirado");
if (resp.status === 403) throw new Error("Acesso negado — verifique sua role");
if (resp.status === 404) throw new Error(`Recurso nao encontrado: ${url}`);
if (resp.status === 422) throw new Error(`Dado invalido: ${detail}`);
if (resp.status === 502) {
const wait = 2 ** attempt * 1000; // 1s, 2s, 4s
console.warn(`Servico externo falhou, aguardando ${wait}ms`);
await new Promise((r) => setTimeout(r, wait));
continue;
}
throw new Error(`HTTP ${resp.status}: ${detail}`);
}
throw new Error(`Falhou apos ${maxRetries} tentativas`);
}
Estrategia de retry para 502
Para erros 502 (servico externo indisponivel), use backoff exponencial:
| Tentativa | Aguardar |
|---|---|
| 1 | 1 segundo |
| 2 | 2 segundos |
| 3 | 4 segundos |
| 4+ | Desistir e notificar |
Quando nao fazer retry
Erros 400, 401, 403, 404 e 422 sao erros do cliente — nao adianta tentar novamente sem corrigir a requisicao.
Rate limit de localizacao
O endpoint PUT /api/v1/locations/me aceita no maximo 1 requisicao a cada 10 segundos por motorista. Exceder esse limite retorna 429 Too Many Requests.