Manejo de Errores¶
Mejores prácticas para manejar errores al usar la API de SubX.
Códigos de Estado HTTP¶
| Código | Significado | Acción |
|---|---|---|
| 200 | Éxito | Procesar la respuesta |
| 400 | Solicitud Incorrecta | Verificar los parámetros de tu solicitud |
| 401 | No Autorizado | Verificar tu clave de API |
| 404 | No Encontrado | El recurso no existe |
| 429 | Límite de Tasa Alcanzado | Esperar Retry-After segundos y reintentar |
| 500 | Error del Servidor | Reintentar con retroceso |
| 502 | Gateway Incorrecto | Fuente no disponible, reintentar más tarde |
Formato de Respuesta de Error¶
Todas las respuestas de error siguen este formato:
Para errores de validación (400), la respuesta puede incluir información detallada del campo:
{
"detail": [
{
"loc": ["query", "year"],
"msg": "ensure this value is greater than or equal to 1900",
"type": "value_error"
}
]
}
Manejo de Errores en Python¶
import requests
import time
def search_with_error_handling(api_key, params, max_retries=3):
"""Buscar con manejo integral de errores."""
headers = {"Authorization": f"Bearer {api_key}"}
url = "https://subx-api.duckdns.org/api/subtitles/search"
for attempt in range(max_retries):
try:
response = requests.get(url, headers=headers, params=params, timeout=10)
# Manejar códigos de estado específicos
if response.status_code == 200:
return response.json()
elif response.status_code == 400:
print(f"Solicitud Incorrecta: {response.json()['detail']}")
return None # No reintentar
elif response.status_code == 401:
print("No Autorizado: Verifica tu clave de API")
return None # No reintentar
elif response.status_code == 404:
print("No Encontrado: El recurso no existe")
return None # No reintentar
elif response.status_code == 429:
# Límite de tasa - usar header Retry-After
retry_after = int(response.headers.get("Retry-After", 60 * (attempt + 1)))
print(f"Límite de tasa alcanzado. Esperando {retry_after}s...")
time.sleep(retry_after)
continue
elif response.status_code >= 500:
# Error del servidor - reintentar
if attempt < max_retries - 1:
wait_time = 60 * (attempt + 1)
print(f"Error del servidor. Reintentando en {wait_time}s...")
time.sleep(wait_time)
continue
else:
print("Error del servidor persiste después de reintentos")
return None
except requests.exceptions.Timeout:
print(f"Tiempo de espera agotado (intento {attempt + 1}/{max_retries})")
if attempt < max_retries - 1:
time.sleep(60 * (attempt + 1))
continue
except requests.exceptions.ConnectionError:
print(f"Error de conexión (intento {attempt + 1}/{max_retries})")
if attempt < max_retries - 1:
time.sleep(60 * (attempt + 1))
continue
except Exception as e:
print(f"Error inesperado: {e}")
return None
return None
Validación Antes de Solicitudes¶
Validar parámetros antes de hacer solicitudes:
def validate_search_params(params):
"""Validar parámetros de búsqueda antes de hacer la solicitud."""
errors = []
# Se requiere al menos un criterio de búsqueda
if not any([params.get(k) for k in ['query', 'title', 'imdb_id', 'public_id']]):
errors.append("Se requiere al menos un criterio de búsqueda")
# Validación de año
if 'year' in params:
year = params['year']
if not (1900 <= year <= 2100):
errors.append(f"El año debe estar entre 1900 y 2100, se obtuvo {year}")
# Validación de límite
if 'limit' in params:
limit = params['limit']
if not (1 <= limit <= 200):
errors.append(f"El límite debe estar entre 1 y 200, se obtuvo {limit}")
if errors:
raise ValueError(f"Parámetros inválidos: {', '.join(errors)}")
return True
Configuración de Timeouts¶
Siempre establecer timeouts para prevenir solicitudes colgadas:
# Timeout corto para verificaciones de salud
response = requests.get("https://subx-api.duckdns.org/api/health", timeout=5)
# Timeout estándar para solicitudes a la API
response = requests.get("https://subx-api.duckdns.org/api/subtitles/search",
headers=headers, params=params, timeout=10)
# Timeout más largo para descargas
response = requests.get(f"https://subx-api.duckdns.org/api/subtitles/{id}/download",
headers=headers, timeout=60)
Próximos Pasos¶
- Rate Limit - Comprender los límites de tasa