Saltar a contenido

Manejo de errores

La API devuelve errores en formato RFC 9457 (Problem Details for HTTP APIs).

Estructura

{
  "type": "/problems/not-found",
  "title": "Not Found",
  "status": 404,
  "detail": "No se encontraron logs para los parámetros indicados.",
  "instance": "/api/v1/dags/my-dag/runs"
}
Campo Descripción
type Identificador del tipo de error
title Título legible del error
status Código HTTP
detail Descripción específica del problema en esta petición
instance Endpoint donde ocurrió el error

Códigos de estado

4xx — Errores del cliente

Código Descripción
400 Bad Request La petición tiene un formato incorrecto
401 Unauthorized Token inválido, expirado o sesión inactiva
403 Forbidden Token válido pero sin permisos suficientes
404 Not Found Recurso o datos no encontrados
422 Unprocessable Entity Parámetros inválidos o combinación no permitida
429 Too Many Requests Se superó el límite de requests. Ver Retry-After en el header de respuesta

5xx — Errores del servidor

Código Descripción
500 Internal Server Error Error inesperado. Inténtalo de nuevo pasados unos segundos.

Errores frecuentes

401 — Token inválido o sesión inactiva

{
  "type": "/problems/unauthorized",
  "title": "Unauthorized",
  "status": 401,
  "detail": "Token inválido o sesión inactiva.",
  "instance": "/api/v1/dags/my-dag/runs"
}

Solución: Obtén un nuevo token e inténtalo de nuevo. El header requerido es:

Authorization: Bearer <token>

403 — Sin permisos

{
  "type": "/problems/forbidden",
  "title": "Forbidden",
  "status": 403,
  "detail": "El token no contiene la información de compañía requerida.",
  "instance": "/api/v1/dags/my-dag/runs"
}

422 — Parámetros inválidos

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

Causas frecuentes:

  • Formato de fecha incorrecto (se espera YYYY-MM-DD)
  • level en minúsculas (debe ser ERROR, no error)
  • start_date posterior a end_date
  • Rango de fechas superior a 7 días en búsqueda de ejecuciones
  • limit fuera del rango permitido para el endpoint

404 — Sin resultados

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

Nota sobre consultas vacías

Los endpoints de consulta de ejecuciones y logs devuelven 200 OK con una lista vacía cuando no hay resultados. El 404 aparece principalmente en endpoints de artefactos individuales o recursos específicos.


Buenas prácticas

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(`Error ${res.status}`);
  return res.json();
}