如何将捕获的异常(其描述和堆栈跟踪)转换为外部使用的str ?

try:
    method_that_can_raise_an_exception(params)
except Exception as e:
    print(complete_exception_description(e))

当前回答

让我们创建一个相当复杂的stacktrace,以演示我们得到完整的stacktrace:

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

def do_something_that_might_error():
    raise_error()

记录完整的堆栈跟踪

最佳实践是为您的模块设置一个记录器。它将知道模块的名称,并且能够更改级别(在其他属性中,例如处理程序)

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

我们可以使用这个日志来获取错误:

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

日志:

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!

所以我们得到的输出和我们有错误时是一样的:

>>> 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!

只获取字符串

如果你真的只想要字符串,使用回溯。取而代之的是Format_exc函数,在这里演示了记录字符串:

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

日志:

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!

其他回答

让我们创建一个相当复杂的stacktrace,以演示我们得到完整的stacktrace:

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

def do_something_that_might_error():
    raise_error()

记录完整的堆栈跟踪

最佳实践是为您的模块设置一个记录器。它将知道模块的名称,并且能够更改级别(在其他属性中,例如处理程序)

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

我们可以使用这个日志来获取错误:

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

日志:

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!

所以我们得到的输出和我们有错误时是一样的:

>>> 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!

只获取字符串

如果你真的只想要字符串,使用回溯。取而代之的是Format_exc函数,在这里演示了记录字符串:

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

日志:

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!

对于Python 3.5+ 使用回溯。TracebackException,它可以处理在任何地方捕获的异常。

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

例子

import traceback

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

> >输出

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

它与from_exec()和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 !!

如果您希望在未处理异常时获得相同的信息,可以这样做。执行import trace,然后:

try:
    ...
except Exception as e:
    print(traceback.print_tb(e.__traceback__))

我使用的是Python 3.7。

>>> 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

您可以使用sys.exc_info()收集信息,并使用traceback模块中的函数对其进行格式化。 下面是一些格式化的例子。

整个异常字符串位于:

>>> 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']

对于使用Python-3的用户

使用回溯模块和异常。__traceback__可以提取堆栈跟踪,如下所示:

使用traceback.extract_stack()获取当前堆栈跟踪 删除最后三个元素(因为它们是堆栈中的条目,使我找到了调试函数) 使用traceback.extract_tb()从异常对象中追加__traceback__ 使用traceback.format_list()格式化整个内容

import traceback
def exception_to_string(excp):
   stack = traceback.extract_stack()[:-3] + traceback.extract_tb(excp.__traceback__)  # add limit=?? 
   pretty = traceback.format_list(stack)
   return ''.join(pretty) + '\n  {} {}'.format(excp.__class__,excp)

一个简单的演示:

def foo():
    try:
        something_invalid()
    except Exception as e:
        print(exception_to_string(e))

def bar():
    return foo()

当我们调用bar()时,我们得到以下输出:

  File "./test.py", line 57, in <module>
    bar()
  File "./test.py", line 55, in bar
    return foo()
  File "./test.py", line 50, in foo
    something_invalid()

  <class 'NameError'> name 'something_invalid' is not defined