在Python中处理异常堆栈跟踪的正确方法

时间:2012-04-11 09:30:21

标签: python exception error-handling stack-trace printstacktrace

我正在编写一些可以在堆栈中生成异常的代码,并且我有一个靠近顶层的层,它捕获这些异常并将它们发送出去以供错误处理模块处理。我想要的是错误处理模块能够将堆栈跟踪打印到其错误日志中,但我发现很难弄清楚这样做的方法是什么。

关于背景的一些注意事项:

  • 代码是多线程的,所以我不确定sys.last_traceback的行为

  • 我尝试在异常本身的构造函数中捕获堆栈。在这种情况下,sys.last_traceback有时是None(因为它只存在于未处理的异常情况下),并且不总是正确的。我目前正在玩弄

    self.stack = traceback.format_stack()[: - 2]

在异常的构造函数中,虽然这在信息方面看起来很有希望,但它并不像是“正确”的方式来做它

  • 我能够找到的所有如何执行此操作的示例都显示如何在except块中打印堆栈跟踪,而不是在以后的错误处理模块中打印,这似乎与我想要的是。 (例如,参见Print current call stack from a method in Python code

  • 我在python docs(http://docs.python.org/library/traceback.html)中挖掘了traceback模块,并且无法弄清楚这是否符合我的要求。它似乎主要关注格式化回溯,因为您可能从sys.last_traceback检索。它有一些使用示例,但没有一个符合我的目的。

我不相信我是第一个想要这样做的人,所以我必须遗漏一些东西。任何正确方向的指针都非常赞赏。

3 个答案:

答案 0 :(得分:2)

处理异常的第一行可能是:

exc_type, exc_value, exc_traceback = sys.exc_info()

您可以存储这些变量或以任何方式传递它们,然后使用traceback模块显示它们。

答案 1 :(得分:0)

如何在要保护的功能中添加一些装饰器?例如:

@onerrorignore
def foo(a, b, c):
    ...

装饰器看起来像:

def onerrorignore(f):
    def _f(*args, **kwargs):
        try:
            ret = f()
        except:
            error_handler.handle(sys.exc_info())
        else:
            return ret
    return _f

答案 2 :(得分:0)

如果我理解你,你想在保持堆栈跟踪的同时重新抛出异常?所以你有一个这样的调用层次结构:

error_handling_module # you want to print the stacktrace here
|
something_else
|
module_excepting_and_rethrowing
|
something_else
|
module_raising_an_error

在你的module_excepting_and_rethrowing中你可以这样做:

except Exception:
   exc_type, exc_value, exc_traceback = sys.exc_info()
   raise NewException, exc_value, exc_traceback

在Python3中你也可以这样做:

 except Exception as e:
     raise NewException from e