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:
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) levelen minúsculas (debe serERROR, noerror)start_dateposterior aend_date- Rango de fechas superior a 7 días en búsqueda de ejecuciones
limitfuera 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();
}