2

考虑以下代码:

df = defer.Deferred()
def hah(_): raise ValueError("4")
df.addCallback(hah)
df.callback(hah)

当它运行时,该异常就会被吃掉。它去哪儿了?我怎样才能让它显示出来?做defer.setDebugging(True)没有效果。

我问这个是因为其他时候,我得到一个打印输出,上面写着“Deferred 中的未处理错误:”。在这种情况下,我该如何实现?我看到,如果我添加一个 errback,df那么 errback 会被异常调用,但我要做的就是打印错误并且什么都不做,而且我不想手动将该处理程序添加到我创建的每个延迟。

4

1 回答 1

7

异常仍然坐在 Deferred 中。此时有两种可能的结果:

  • 您可以向 Deferred 添加 errback。一旦你这样做,它将被调用失败,其中包含引发的异常。
  • 您可以让 Deferred 被垃圾收集(显式删除df,或从函数返回,或以任何其他方式丢失引用)。这会触发“延迟中的未处理错误”代码。

因为可以随时将 errback 添加到 Deferred(即上面的第一点),所以 Deferred 不会立即对其他未处理的错误执行任何操作。他们不知道错误是真的没有处理,还是到目前为止还没有处理。只有当 Deferred 被垃圾回收时,它才能确定没有其他人会处理异常,所以这就是它被记录的时候。

通常,您希望确保在 Deferred 上有 errbacks,这正是因为有时很难预测 Deferred 何时会被垃圾收集。这可能需要很长时间,这意味着如果您没有附加自己的 errback,您可能需要很长时间才能了解异常。

这不一定是一个可怕的负担。任何从另一个 Deferred (b) 上的回调返回的 Deferred (a)(即发生链接时)都会将其错误传递给 b。所以 (a) 不需要额外的 errbacks 来记录和报告,只有 (b) 需要。如果您有一个复杂且涉及许多异步操作的单一逻辑任务,那么几乎所有涉及这些操作的 Deferred 都应将其结果(成功或失败)引导到一个代表逻辑操作的主要 Deferred。您通常只需要对那个 Deferred 进行特殊的错误处理行为,这样您就可以处理来自任何其他所涉及的 Deferred 的错误。

于 2010-09-30T13:31:26.027 回答