我正在实现一个应该返回延迟的函数。在该函数内部,我决定发生错误。
我可以提出错误:
raise ValueError("...")
然后该函数不再返回延迟。我不想在任何时候使用maybeDeferred
。
或者,我可以像这样返回延期:
return defer.fail(Failure(ValueError(...)))
这样可行,但Failure
不会包含堆栈跟踪,因此很难跟踪错误。
到目前为止,我发现的最好的事情是:
try:
raise ValueError("...")
except:
return defer.fail()
我得到延迟回来,Failure
包含堆栈跟踪。但这相当冗长。
有没有更好的方法让我失踪?
我有点惊讶,这种常见的事情并不是一个优雅的解决方案。
答案 0 :(得分:1)
这个问题让我感到有些惊讶,我不得不考虑一下原因。
如果你想要的只是因为追踪冒泡并且被全局错误处理程序记录而失败,你不需要返回defer.fail()
。提出异常会得到这种行为。
区别在于这样的情况:
foo().addErrback(fooErrorHandler)
在这种情况下,如果延迟的结果是失败,则会调用fooErrorHandler
,而当同步引发异常时,不会。这需要更加繁琐的形式:
try:
foo().addErrback(fooErrorHandler)
except Exception, err:
fooErrorHandler(Failure(err))
当然看起来很糟糕。但我们现在谈论的情况现在是
的情况这可能就是为什么它没有像你想象的那样普遍存在。
当然,它可能不会成为常见问题的另一个原因是人们经常懒惰地定义错误处理程序,并且常常懒得记录他们的代码可能引发的各种异常。
啊哈哈,还有其他可能增加了我的困惑:Failure
确实知道如何存储其堆栈,但它明确地更改为not do this unless there's a traceback表现原因。该提交消息描述的获取回溯的方法与帖子中的四行try / except示例相同。
我想这可能是Failure()
的选项(如captureVars
所示),或者是替代构造函数方法,如果这确实足以保证它。