Ir para o conteúdo

Tratamento de erros

A API retorna erros no formato RFC 9457 (Problem Details for HTTP APIs).

Estrutura

{
  "type": "/problems/not-found",
  "title": "Not Found",
  "status": 404,
  "detail": "Nenhum log encontrado para os parâmetros indicados.",
  "instance": "/api/v1/dags/my-dag/runs"
}
Campo Descrição
type Identificador do tipo de erro
title Título legível do erro
status Código HTTP
detail Descrição específica do problema nesta requisição
instance Endpoint onde o erro ocorreu

Códigos de status

4xx — Erros do cliente

Código Descrição
400 Bad Request A requisição tem formato incorreto
401 Unauthorized Token inválido, expirado ou sessão inativa
403 Forbidden Token válido, mas sem permissões suficientes
404 Not Found Recurso ou dados não encontrados
422 Unprocessable Entity Parâmetros inválidos ou combinação não permitida
429 Too Many Requests Limite de requisições excedido. Ver Retry-After no header de resposta

5xx — Erros do servidor

Código Descrição
500 Internal Server Error Erro inesperado. Tente novamente após alguns segundos.

Erros frequentes

401 — Token inválido ou sessão inativa

{
  "type": "/problems/unauthorized",
  "title": "Unauthorized",
  "status": 401,
  "detail": "Token inválido ou sessão inativa.",
  "instance": "/api/v1/dags/my-dag/runs"
}

Solução: Obtenha um novo token e tente novamente. O header necessário é:

Authorization: Bearer <token>

403 — Sem permissões

{
  "type": "/problems/forbidden",
  "title": "Forbidden",
  "status": 403,
  "detail": "O token não contém as informações de empresa necessárias.",
  "instance": "/api/v1/dags/my-dag/runs"
}

422 — Parâmetros inválidos

{
  "type": "/problems/validation-error",
  "title": "Unprocessable Entity",
  "status": 422,
  "detail": "start_date é posterior a end_date.",
  "instance": "/api/v1/dags/my-dag/runs"
}

Causas frequentes:

  • Formato de data incorreto (esperado YYYY-MM-DD)
  • level em minúsculas (deve ser ERROR, não error)
  • start_date posterior a end_date
  • Intervalo de datas superior a 7 dias na busca de execuções
  • limit fora do intervalo permitido para o endpoint

404 — Sem resultados

{
  "type": "/problems/not-found",
  "title": "Not Found",
  "status": 404,
  "detail": "Nenhum log encontrado para os filtros especificados.",
  "instance": "/api/v1/dags/my-dag/runs/2026-05-01/run-id/phases/extract/logs"
}

Nota sobre consultas vazias

Os endpoints de consulta de execuções e logs retornam 200 OK com uma lista vazia quando não há resultados. O 404 aparece principalmente em endpoints de artefatos individuais ou recursos específicos.


Boas práticas

import requests, time

def request_with_retry(url, headers, params):
    response = requests.get(url, headers=headers, params=params)

    if response.status_code == 401:
        headers["Authorization"] = f"Bearer {refresh_token()}"
        response = requests.get(url, headers=headers, params=params)

    elif response.status_code == 422:
        error = response.json()
        raise ValueError(f"Parâmetros inválidos: {error['detail']}")

    elif response.status_code == 429:
        retry_after = int(response.headers.get("Retry-After", 60))
        time.sleep(retry_after)
        response = requests.get(url, headers=headers, params=params)

    elif response.status_code >= 500:
        time.sleep(2)
        response = requests.get(url, headers=headers, params=params)

    response.raise_for_status()
    return response.json()
async function fetchWithRetry(url, token, params) {
  const query = new URLSearchParams(params).toString();
  const headers = { Authorization: `Bearer ${token}` };

  let res = await fetch(`${url}?${query}`, { headers });

  if (res.status === 401) {
    token = await refreshToken();
    headers.Authorization = `Bearer ${token}`;
    res = await fetch(`${url}?${query}`, { headers });
  }

  if (res.status === 422) {
    const err = await res.json();
    throw new Error(`Parâmetros inválidos: ${err.detail}`);
  }

  if (res.status === 429) {
    const retryAfter = parseInt(res.headers.get('Retry-After') || '60', 10);
    await new Promise(r => setTimeout(r, retryAfter * 1000));
    res = await fetch(`${url}?${query}`, { headers });
  }

  if (res.status >= 500) {
    await new Promise(r => setTimeout(r, 2000));
    res = await fetch(`${url}?${query}`, { headers });
  }

  if (!res.ok) throw new Error(`Erro ${res.status}`);
  return res.json();
}