Obtenga la descripción de la excepción y el seguimiento de la pila que provocó una excepción, todo como una cadena

Resuelto bluish asked hace 13 años • 12 respuestas

¿Cómo convertir un capturado Exception(su descripción y seguimiento de la pila) en uno strpara uso externo?

try:
    method_that_can_raise_an_exception(params)
except Exception as e:
    print(complete_exception_description(e))
bluish avatar Dec 30 '10 23:12 bluish
Aceptado

Ver el tracebackmódulo, específicamente la format_exc()función. Aquí .

import traceback

try:
    raise ValueError
except ValueError:
    tb = traceback.format_exc()
else:
    tb = "No error"
finally:
    print tb
kindall avatar Dec 30 '2010 17:12 kindall

Creemos un seguimiento de pila bastante complicado para demostrar que obtenemos el seguimiento de pila completo:

def raise_error():
    raise RuntimeError('something bad happened!')

def do_something_that_might_error():
    raise_error()

Registrar el seguimiento de pila completo

Una mejor práctica es tener un registrador configurado para su módulo. Sabrá el nombre del módulo y podrá cambiar niveles (entre otros atributos, como controladores)

import logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)

Y podemos usar este registrador para obtener el error:

try:
    do_something_that_might_error()
except Exception as error:
    logger.exception(error)

Qué registros:

ERROR:__main__:something bad happened!
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "<stdin>", line 2, in do_something_that_might_error
  File "<stdin>", line 2, in raise_error
RuntimeError: something bad happened!

Y entonces obtenemos el mismo resultado que cuando tenemos un error:

>>> do_something_that_might_error()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in do_something_that_might_error
  File "<stdin>", line 2, in raise_error
RuntimeError: something bad happened!

Obteniendo solo la cuerda

Si realmente solo desea la cadena, use la traceback.format_excfunción en su lugar, demostrando cómo registrar la cadena aquí:

import traceback
try:
    do_something_that_might_error()
except Exception as error:
    just_the_string = traceback.format_exc()
    logger.debug(just_the_string)

Qué registros:

DEBUG:__main__:Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "<stdin>", line 2, in do_something_that_might_error
  File "<stdin>", line 2, in raise_error
RuntimeError: something bad happened!
Russia Must Remove Putin avatar Jul 16 '2015 03:07 Russia Must Remove Putin

Con Python 3, el siguiente código formateará un Exceptionobjeto exactamente como se obtendría usando traceback.format_exc():

import traceback

try: 
    method_that_can_raise_an_exception(params)
except Exception as ex:
    print(''.join(traceback.format_exception(etype=type(ex), value=ex, tb=ex.__traceback__)))

La ventaja es que solo Exceptionse necesita el objeto (gracias al __traceback__atributo registrado) y, por lo tanto, se puede pasar más fácilmente como argumento a otra función para su posterior procesamiento.

Erwin Mayer avatar Mar 01 '2016 00:03 Erwin Mayer

Para el uso de Python 3.5+ , puede manejar excepciones detectadas en cualquier lugar .
traceback.TracebackException

def print_trace(ex: BaseException):
    print(''.join(traceback.TracebackException.from_exception(ex).format()))

Ejemplo

import traceback

try:
    1/0
except Exception as ex:
    print(''.join(traceback.TracebackException.from_exception(ex).format()))

>> Salida

Traceback (most recent call last):
  File "your_file_name_here.py", line 29, in <module>
    1/0
ZeroDivisionError: division by zero

Es idéntico a format_exc()y format_exception():

    a = ''.join(traceback.TracebackException.from_exception(ex).format())
    b = traceback.format_exc()
    c = ''.join(traceback.format_exception(type(ex), ex, ex.__traceback__))
    print(a == b == c)  # This is True !!
don_vanchos avatar Nov 08 '2019 10:11 don_vanchos
>>> import sys
>>> import traceback
>>> try:
...   5 / 0
... except ZeroDivisionError as e:
...   type_, value_, traceback_ = sys.exc_info()
>>> traceback.format_tb(traceback_)
['  File "<stdin>", line 2, in <module>\n']
>>> value_
ZeroDivisionError('integer division or modulo by zero',)
>>> type_
<type 'exceptions.ZeroDivisionError'>
>>>
>>> 5 / 0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero

Utiliza sys.exc_info() para recopilar la información y las funciones en el tracebackmódulo para formatearla. A continuación se muestran algunos ejemplos para formatearlo.

Toda la cadena de excepción está en:

>>> ex = traceback.format_exception(type_, value_, traceback_)
>>> ex
['Traceback (most recent call last):\n', '  File "<stdin>", line 2, in <module>\n', 'ZeroDivisionError: integer division or modulo by zero\n']
aeter avatar Dec 30 '2010 17:12 aeter