Códigos de Estado y Errores
Un aspecto crucial del desarrollo web es el manejo de fallos. Explora cómo evaluar los códigos de estado HTTP, lanzar excepciones automáticas y manejar errores de conexión o tiempos de espera agotados.
Interactuar con servicios web requiere un control de flujos preparado para el fallo. Las redes IP son inherentemente impredecibles y los servidores remotos pueden rechazar datos o sufrir caídas. Este capítulo profundiza en cómo la biblioteca requests gestiona estos escenarios. Aprenderás a inspeccionar códigos de estado HTTP mediante propiedades nativas y constantes semánticas, a interceptar fallas de infraestructura como pérdidas de conexión o caídas de DNS con la jerarquía RequestException, y a usar raise_for_status() para automatizar excepciones. Finalmente, aprenderás a distinguir errores del cliente (4xx) de fallos del servidor (5xx) para diseñar flujos resilientes.
8.1. Verificación de códigos de estado
Cuando el servidor web procesa una petición HTTP, devuelve un código numérico de tres dígitos conocido como código de estado. Este número clasifica el resultado de la operación. La biblioteca requests proporciona múltiples mecanismos intuitivos para evaluar estos códigos antes de proceder con el procesamiento de los datos.
Estructura general de los códigos de estado
Los códigos se agrupan en cinco categorías según su primer dígito. Comprender esta jerarquía facilita el diseño de flujos de control lógicos en el código:
TEXT
La propiedad .status_code
El método más directo para evaluar la respuesta del servidor es inspeccionar el atributo .status_code expuesto por el objeto Response. Este contiene un valor entero (int).
Python
Evaluación booleana implícita del objeto Response
Una de las características más utilizadas de la biblioteca es la conversión implícita a booleano del objeto Response. Si se evalúa una respuesta directamente en una sentencia if, requests verificará internamente si el código de estado se encuentra en el rango de éxito (mayor o igual a 200 y menor que 400).
Python
Advertencia de diseño: Aunque la evaluación booleana es muy cómoda para flujos rápidos, no distingue entre una redirección (3xx) y un éxito directo (2xx), ni tampoco entre un error de autenticación (401) y una página no encontrada (404). Para lógicas complejas, es preferible la verificación detallada.
El objeto de códigos internos: requests.codes
Para evitar el uso de "números mágicos" (valores numéricos fijos en el código que reducen la legibilidad), requests incluye un diccionario con atributos nombrado requests.codes. Este objeto asocia los números de estado con nombres descriptivos en inglés, permitiendo escribir código más semántico.
Python
El objeto requests.codes es flexible y admite múltiples sinónimos para un mismo código, lo que facilita la adaptación al vocabulario de preferencia del desarrollador:
TEXT
8.2. El método raise_for_status()
En lugar de evaluar manualmente los códigos de estado mediante estructuras condicionales if/else, la biblioteca requests ofrece un mecanismo basado en excepciones para gestionar las respuestas fallidas de forma centralizada. Esto se logra mediante el método raise_for_status().
Comportamiento del método
El método raise_for_status() inspecciona el código de estado de la respuesta de manera interna. Su comportamiento varía estrictamente según el resultado de la petición:
- Respuestas exitosas (Códigos 2xx y 3xx): El método no realiza ninguna acción y retorna
None. El flujo de ejecución del programa continúa con la siguiente línea de código de forma completamente normal. - Respuestas fallidas (Códigos 4xx y 5xx): El método interrumpe el flujo del programa lanzando una excepción de tipo
HTTPError.
Sintaxis básica e integración con bloques try-except
La forma recomendada de implementar este método es envolviendo la llamada dentro de una estructura de control de excepciones try-except. Esto permite separar la lógica principal de la aplicación del manejo de errores de red.
Python
Anatomía del error HTTPError
Cuando raise_for_status() lanza una excepción HTTPError, el objeto de la excepción contiene información detallada sobre la petición original y la respuesta del servidor. El mensaje de error generado automáticamente sigue una estructura estandarizada que facilita la depuración en los registros del sistema (logs):
TEXT
Es posible acceder programáticamente a los objetos internos de la petición y de la respuesta desde la propia excepción a través de los atributos .request y .response:
Python
Ventajas de uso frente a la verificación manual
- Código más limpio (Clean Code): Elimina la necesidad de anidar múltiples bloques condicionales
if respuesta.status_code == ...después de cada petición HTTP. - Centralización del error: Permite agrupar la gestión de fallos de múltiples peticiones consecutivas dentro de un único bloque
try-exceptgeneral. - Interrupción temprana (Fail-Fast): Asegura que el programa no intente procesar un cuerpo de respuesta vacío o corrupto (como un HTML de error de Cloudflare) asumiendo que los datos son válidos.
8.3. Manejo de excepciones RequestException
El desarrollo de aplicaciones robustas que interactúan con servicios web requiere contemplar fallas más allá de las respuestas del servidor (errores HTTP). Los problemas de infraestructura, cortes de energía en la red o nombres de dominio mal escritos impiden que una petición se complete. En la biblioteca requests, todas estas anomalías se gestionan a través de una jerarquía de excepciones estructurada.
La clase base RequestException
En la raíz de todas las excepciones lanzadas por la biblioteca se encuentra requests.exceptions.RequestException. Esta clase actúa como un paraguas para cualquier tipo de error que ocurra durante el ciclo de vida de una petición.
Capturar RequestException garantiza que el programa no sufra una caída inesperada debido a problemas de comunicación HTTP, independientemente de la causa exacta.
Jerarquía de excepciones comunes
Para implementar estrategias de recuperación específicas, es fundamental conocer las subclases principales que heredan de RequestException:
TEXT
ConnectionError: Se produce cuando hay un problema físico o de enrutamiento subyacente. Por ejemplo, si el cable de red se desconecta, el servidor DNS no puede resolver el dominio, o el puerto del servidor remoto está cerrado.Timeout: Ocurre cuando el servidor remoto tarda más tiempo del configurado en responder o en establecer la conexión inicial.HTTPError: Se origina exclusivamente cuando se invoca explícitamente el métodoraise_for_status()ante una respuesta con estado de error del cliente o del servidor.
Buenas prácticas para la captura de excepciones
El orden en el que se definen los bloques except es crucial en Python. Se debe proceder siempre desde la excepción más específica hacia la más general. Si se captura RequestException en el primer bloque, las excepciones hijas inferiores nunca serán evaluadas de forma individual.
El siguiente ejemplo expone la estructura estándar para el manejo profesional de fallas en entornos de producción:
Python
8.4. Distinción entre errores del cliente y servidor
El último paso para dominar el control de flujo en la comunicación HTTP consiste en diferenciar el origen de un fallo cuando este se produce en la capa de la aplicación (códigos 4xx y 5xx). Clasificar correctamente si la responsabilidad del error recae sobre el cliente o sobre el servidor determina si la aplicación debe corregir los datos enviados o si debe esperar a que el servicio remoto se estabilice.
Errores del Cliente (Rango 4xx)
Los códigos de estado que comienzan con el dígito 4 indican que la petición enviada por la aplicación contiene alguna anomalía o no cumple con los requisitos del servidor.
Regla de oro: Ante un error 4xx, no se debe reintentar la misma petición de forma automática sin realizar modificaciones previas, ya que el resultado volverá a ser un fallo de manera invariable.
Los códigos 4xx más habituales en la integración de APIs y sistemas web son:
400 Bad Request: El servidor no puede entender la petición debido a una sintaxis defectuosa (por ejemplo, un JSON mal estructurado).401 Unauthorized: La petición carece de credenciales de autenticación válidas o el token proporcionado ha expirado.403 Forbidden: El servidor entiende quién es el cliente, pero este no posee los permisos necesarios para acceder al recurso solicitado.404 Not Found: El recurso o la URL especificada no existen en el servidor remoto.
Errores del Servidor (Rango 5xx)
Los códigos de estado que comienzan con el dígito 5 reflejan que el servidor web tiene constancia de haber encontrado un error interno o es incapaz de procesar la solicitud debido a un fallo de su propia infraestructura.
Regla de oro: Ante un error 5xx, la petición original suele ser estructuralmente correcta. Por lo tanto, es seguro implementar estrategias de reintento tras un intervalo de tiempo prudencial, ya que el problema podría ser transitorio.
Los códigos 5xx más comunes en entornos de producción abarcan:
500 Internal Server Error: Una condición genérica e inesperada ocurrió en el servidor (comúnmente una excepción no controlada en su código interno).502 Bad Gateway: El servidor, actuando como puerta de enlace o proxy, recibió una respuesta inválida del servidor principal río arriba.503 Service Unavailable: El servidor no está disponible momentáneamente debido a una sobrecarga temporal o a labores de mantenimiento planificadas.504 Gateway Timeout: El servidor proxy no recibió una respuesta a tiempo del servidor de datos subyacente.
Implementación del filtrado programático en Python
El objeto Response no cuenta con propiedades booleanas directas para aislar de forma individual el origen exacto del fallo (como un hipotético .is_client_error). Sin embargo, se puede implementar esta lógica de manera elegante evaluando si el código se encuentra dentro de los rangos numéricos correspondientes:
Python
Resumen del capítulo
El Capítulo 8: Códigos de Estado y Errores proporciona las bases para dotar a las aplicaciones de resiliencia frente a los fallos inherentes a la comunicación a través de redes IP:
- Evaluación directa e implícita: Aprendimos a inspeccionar valores numéricos concretos con
.status_code, a utilizar constantes semánticas legibles mediante el objetorequests.codesy a emplear la conversión booleana implícita para verificar de forma rápida si una petición se completó sin anomalías. - Control mediante excepciones: Estudiamos cómo automatizar la interrupción del flujo del programa con el método
.raise_for_status(), el cual lanza excepciones específicas cuando detecta códigos no exitosos. - Jerarquía de fallos: Analizamos la estructura de excepciones encabezada por
RequestExceptionpara interceptar de manera robusta problemas de resolución DNS (ConnectionError), pérdidas de conexión por lentitud (Timeout) o errores en la capa de aplicación (HTTPError). - Origen de la falla: Establecimos los criterios de diseño para diferenciar los errores cometidos por nuestra propia aplicación (rango 4xx) de aquellos causados por caídas o mantenimiento en la infraestructura del servidor remoto (rango 5xx), habilitando la toma de decisiones lógicas basadas en datos para la tolerancia a fallos.
© 2026 Esdocu. Contenido bajo licencia MIT.
Editar esta página