Cuando una excepción no es controlada, Python muestra una secuencia de archivos, líneas y llamadas que condujo al fallo. Esa secuencia es el traceback. El módulo traceback en Python permite capturar, formatear, limitar, almacenar y mostrar esta información de manera controlada, por lo que resulta útil en herramientas de terminal, APIs, workers, tareas asíncronas, sistemas de logging y utilidades de diagnóstico.
Esta guía cubre print_exc(), format_exc(), extract_tb(), TracebackException, StackSummary y clear_frames(). Complementa nuestros artículos sobre depuración con pdb, introspección con inspect, diagnóstico de rendimiento y PermissionError.
Qué contiene un traceback
Una excepción guarda una referencia a su objeto de traceback en __traceback__. Cada entrada representa un frame de la pila de llamadas e incluye archivo, número de línea, nombre de función y contexto del código fuente.
def dividir(a, b):
return a / b
def ejecutar():
return dividir(10, 0)
try:
ejecutar()
except ZeroDivisionError as error:
print(type(error.__traceback__))Los frames forman una cadena mediante tb_next. Normalmente no es necesario recorrerla manualmente porque el módulo proporciona APIs de extracción y formateo.
Imprimir la excepción actual con print_exc()
Dentro de un bloque except, traceback.print_exc() genera una salida similar a la del intérprete.
import traceback
try:
ejecutar()
except Exception:
traceback.print_exc()El destino predeterminado es sys.stderr. También puede enviarse a un archivo o flujo compatible:
import sys
try:
ejecutar()
except Exception:
traceback.print_exc(file=sys.stdout)Es práctico en herramientas interactivas. En producción, integra el error con logging estructurado y monitoreo en lugar de imprimirlo sin contexto.
Obtener el traceback como texto
format_exc() devuelve una cadena completa en vez de imprimir inmediatamente.
try:
ejecutar()
except Exception:
texto = traceback.format_exc()
enviar_a_monitoreo(texto)El resultado puede guardarse en un reporte interno o asociarse a una tarea fallida. No muestres tracebacks completos a usuarios finales porque pueden revelar rutas, funciones internas, consultas y otros datos sensibles.
Usar logging.exception()
El módulo estándar logging ya sabe incluir el traceback activo. Dentro del manejador, logger.exception() registra un mensaje y la excepción actual.
import logging
logger = logging.getLogger(__name__)
try:
ejecutar()
except Exception:
logger.exception("La operación falló")La documentación oficial de logging explica handlers, formatters, filtros y niveles. Evita registrar la misma excepción en todas las capas, porque genera duplicados y altera las métricas.
Limitar la cantidad de frames
Las funciones de impresión y formato aceptan limit. Los valores positivos y negativos seleccionan extremos distintos de la pila según la API.
try:
ejecutar()
except Exception:
traceback.print_exc(limit=-3)Los últimos frames suelen estar cerca de la instrucción que falló. Sin embargo, eliminar demasiado contexto puede ocultar el handler, job o plugin que inició la operación.
Formatear solo la excepción
Cuando la pila no es necesaria, format_exception_only() devuelve el tipo y el mensaje.
try:
ejecutar()
except Exception as error:
lineas = traceback.format_exception_only(error)
mensaje = "".join(lineas)
print(mensaje)Los errores de sintaxis reciben información adicional sobre línea y posición. Las notas añadidas con add_note() también aparecen en versiones actuales.
Extraer datos estructurados
extract_tb() convierte el traceback en un StackSummary compuesto por objetos FrameSummary.
try:
ejecutar()
except Exception as error:
resumen = traceback.extract_tb(error.__traceback__)
for frame in resumen:
print(frame.filename, frame.lineno, frame.name, frame.line)Este formato sirve para generar JSON, agrupar incidentes por archivo y línea, crear fingerprints o eliminar prefijos privados antes de enviar datos a un servicio externo.
Capturar la pila sin una excepción
extract_stack() y format_stack() inspeccionan la pila actual. Pueden revelar quién llamó una operación sensible o ayudar cuando una tarea parece bloqueada.
def funcion_sensible():
pila = traceback.extract_stack(limit=-5)
for frame in pila:
print(frame.name, frame.lineno)La captura tiene coste. Evita realizarla en cada petición exitosa de un servicio con alto tráfico; usa muestreo o modos de diagnóstico.
Guardar diagnósticos con TracebackException
Conservar la excepción puede retener sus frames y todos los objetos accesibles desde variables locales. TracebackException captura información suficiente para formatear después sin mantener vivo el grafo completo.
from traceback import TracebackException
try:
ejecutar()
except Exception as error:
capturado = TracebackException.from_exception(
error,
limit=-10,
capture_locals=False,
compact=True,
)
texto = "".join(capturado.format())La documentación oficial de traceback describe esta clase como la opción flexible para renderizado posterior y mejor administración de memoria.
Cuidado con capture_locals
capture_locals=True guarda representaciones de variables locales de cada frame.
capturado = TracebackException.from_exception(
error,
capture_locals=True,
)Puede revelar contraseñas, tokens, datos personales, cuerpos de peticiones y claves privadas. También puede crear registros enormes. Habilítalo solo en entornos controlados, aplica enmascaramiento y restringe el acceso.
Excepciones encadenadas
Cuando ocurre una nueva excepción durante el tratamiento de otra, Python conserva la original en __context__. La sintaxis raise NuevaExcepcion() from original define una causa explícita en __cause__.
try:
int("abc")
except ValueError as original:
raise RuntimeError("Configuración inválida") from originalLos formatters incluyen la cadena cuando chain=True, que es el valor predeterminado. Así se conserva el fallo técnico y se añade una explicación del dominio.
ExceptionGroup
Las operaciones concurrentes pueden producir un ExceptionGroup con varios errores. TracebackException expone las excepciones anidadas y permite limitar anchura y profundidad.
capturado = TracebackException.from_exception(
error,
max_group_width=8,
max_group_depth=4,
)Los límites evitan reportes gigantes cuando un lote produce cientos de errores similares.
Liberar referencias de frames
Si el código trabaja directamente con un traceback real, clear_frames() elimina variables locales de sus frames.
try:
ejecutar()
except Exception as error:
tb = error.__traceback__
try:
procesar(traceback.extract_tb(tb))
finally:
traceback.clear_frames(tb)Esto reduce retención accidental en workers persistentes. Para diagnósticos que deben almacenarse, convertir a TracebackException continúa siendo la opción preferida.
Sanitizar rutas y mensajes
Un traceback puede revelar directorios del servidor, nombres de usuario, estructura del código, argumentos y fragmentos de fuente. Antes de exportarlo, elimina prefijos privados y aplica una política de datos.
from pathlib import Path
def frame_publico(frame):
return {
"archivo": Path(frame.filename).name,
"linea": frame.lineno,
"funcion": frame.name,
}El usuario final debería recibir un mensaje breve y un identificador de incidente. El diagnóstico completo debe permanecer en logs con acceso controlado.
Personalizar StackSummary
StackSummary puede subclasificarse y su método format_frame_summary() puede omitir internals del framework, normalizar rutas o aplicar un formato propio.
No elimines el primer frame útil de la aplicación ni la ubicación que lanzó el error. Prueba el formatter con recursión, código generado, archivos sin fuente y excepciones encadenadas.
Un traceback no es un depurador completo
La pila explica cómo el control llegó al fallo, pero no siempre por qué el estado se volvió inválido. Combínala con logs estructurados, métricas, pruebas reproducibles y pdb. Los crashes nativos, deadlocks o fallos del intérprete pueden requerir faulthandler y herramientas del sistema operativo.
Errores frecuentes
- Usar
format_exc()fuera de un manejador activo. - Mostrar tracebacks completos a visitantes web.
- Capturar variables locales con secretos.
- Guardar excepciones y frames indefinidamente.
- Registrar el mismo fallo en todas las capas.
- Eliminar tantos frames que desaparece el origen.
- Tratar errores de validación esperados como incidentes críticos.
- Descartar las causas encadenadas.
Buenas prácticas
- Usa
logger.exception()en la capa responsable del incidente. - Convierte a
TracebackExceptionpara almacenamiento posterior. - Mantén
capture_localsdesactivado por defecto. - Oculta rutas y valores sensibles.
- Limita pilas y grupos muy grandes.
- Limpia frames cuando manipules tracebacks vivos.
- Entrega IDs de correlación al usuario.
- Prueba cadenas, grupos y errores de sintaxis.
Conclusión
El módulo traceback en Python convierte la pila de excepciones en información que puede imprimirse, formatearse, filtrarse y almacenarse. Las funciones de nivel superior resuelven diagnósticos inmediatos, mientras TracebackException, StackSummary y FrameSummary soportan sistemas estructurados y persistentes.
El uso seguro requiere equilibrio: conservar contexto suficiente para investigar sin filtrar datos privados ni mantener un gran grafo de objetos vivos. Con logging centralizado, sanitización, límites y limpieza de frames, los tracebacks se convierten en datos operativos confiables y no solo en texto rojo del terminal.







