Skip to content

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:

{
  "detail": "Mensagem descritiva do erro"
}

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

{"detail": "Token expirado ou invalido"}

Solucao: Refaca o login ou use o refresh_token para obter um novo access_token. Ver Autenticacao.

403 — Role insuficiente

{"detail": "Acesso negado: role insuficiente"}

Solucao: Verifique se esta usando credenciais com a role correta para o endpoint.

404 — Entrega nao encontrada

{"detail": "Entrega nao encontrada"}

422 — Transicao de status invalida

{"detail": "Transicao invalida: entrega ja esta em in_progress"}

422 — Saldo insuficiente

{"detail": "Saldo insuficiente para saque"}

502 — Servico externo indisponivel

{"detail": "Erro ao calcular rota: servico OpenRouteService 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.