Curso de Python / Leer errores y depurar programas con logging

Para depurar un programa, empieza por la excepción final del traceback y por el archivo y la línea relevantes, y reproduce la entrada que falló. El depurador permite observar el estado de ejecución; logging registra eventos seleccionados con niveles de gravedad definidos.

Reducir el fallo a un caso reproducible

Lee el tipo de excepción y su mensaje al final del traceback y después localiza tu propio código en la cadena de llamadas. Antes de modificar una biblioteca, identifica qué datos y configuración llegaron hasta ella. Un ejemplo mínimo elimina variables que no intervienen en el fallo.

En VS Code, detén la ejecución en un punto de interrupción e inspecciona las variables, la pila de llamadas y la instrucción siguiente. Observar el estado antes del fallo suele aportar más información que añadir impresiones después de una línea a la que el programa nunca llega.

La guía oficial de logging explica los registros. La propagación de excepciones permite decidir qué fallos puede resolver cada capa.

Ejecutar un cálculo con registro de eventos

Guarda el siguiente programa como logging_demo.py en UTF-8. Ejecuta python logging_demo.py desde la carpeta de práctica y el entorno virtual del proyecto. Fuera del entorno en macOS o Ubuntu, utiliza python3 si corresponde.

import logging

logging.basicConfig(level=logging.INFO, format="%(levelname)s:%(message)s")
logger = logging.getLogger(__name__)

def calculate(amounts):
    logger.debug("count=%s", len(amounts))
    if any(x < 0 for x in amounts):
        raise ValueError("negative amount")
    return sum(amounts)

try:
    total = calculate([3500, 8000, 2500])
except ValueError:
    logger.exception("calculation failed")
    raise SystemExit(1)
else:
    logger.info("total=%s", total)
print("finished")

La salida estándar esperada es:

finished

El bloque anterior muestra solo la salida estándar. El registro también contiene INFO:total=14000, normalmente en la salida de error estándar. Esos canales pueden capturarse o presentarse por separado, de modo que el orden visual observado por una herramienta no siempre representa una única secuencia combinada.

Elegir niveles y distinguir el resultado del proceso

Nivel Uso habitual
DEBUG Detalle para diagnosticar
INFO Progreso y resultados normales
WARNING Una situación que requiere atención
ERROR Una operación fallida

La configuración INFO del ejemplo oculta el mensaje DEBUG con la cantidad de elementos. Aplica los niveles según una política coherente. Si guardas registros en archivos, también necesitas decidir su ubicación, rotación, conservación y permisos.

Registrar un fallo no hace que el proceso termine automáticamente con error. Aquí, el manejador registra una excepción no recuperable y lanza SystemExit(1). Por eso la prueba con un importe negativo no imprime finished. Con datos válidos registra INFO, imprime finished y termina con código cero.

Inmediatamente después de ejecutar el programa, consulta $LASTEXITCODE en PowerShell o echo $? en una terminal de macOS o Ubuntu. La referencia de sys.exit explica el significado del estado de salida.

Introducir un fallo y conservar contexto útil

  1. Sustituye un importe por -1 y comprueba el registro de fallo, el traceback y el estado de salida distinto de cero.
  2. Restaura los datos y cambia el nivel a DEBUG para observar count=3.
  3. Restaura también el nivel INFO y verifica otra vez el resultado normal.

No ocultes el problema mediante un manejador amplio vacío. Registra qué operación falló y propaga el error cuando quien llama deba reaccionar. Evita contraseñas, cabeceras de autenticación y registros completos de datos personales; registrar objetos grandes repetidamente también consume tiempo y almacenamiento.

La orientación para el usuario y el diagnóstico técnico sirven a lectores distintos. Cuando el caso mínimo y su comportamiento esperado están claros, las pruebas automatizadas permiten convertirlo en una comprobación repetible.