如何捕获源自reactor.stop()的Deferred中未处理的错误

2023-12-31

我是扭曲的新手,并且在使用以下脚本时遇到问题。

当我运行以下命令时:

#!/usr/bin/env python
from twisted.internet import defer
from twisted.web.client import getPage, reactor

def success(results):
  print 'success'

def error(results):
  print 'error'
  return results

def finished(results):
  print 'finished'
  reactor.stop()

tasks = []

d = getPage('thiswontwork').addCallback(success).addErrback(error)
tasks.append(d)

dl = defer.DeferredList(tasks)
dl.addCallback(finished)

reactor.run()

我得到以下输出:

error
finished
Unhandled error in Deferred:
Unhandled Error
Traceback (most recent call last):
Failure: twisted.internet.error.ConnectionRefusedError: Connection was refused by other side: 61: Connection refused.

我的问题是,当我似乎通过错误回调捕获了错误时,为什么会收到未处理的错误?


问题是在你的error你一定会回来result考虑到它是由错误调用的,返回的是Failure对象,并返回一个Failureobject 是重新引发错误状态的两个标准之一。请参阅以下简介krondo 的扭曲介绍 - 第 9 部分 http://krondo.com/blog/?p=1825:

现在,在同步代码中,我们可以使用 raise 关键字而不带任何参数“重新引发”异常。这样做会引发我们正在处理的原始异常,并允许我们对错误采取一些操作,而无需完全处理它。事实证明我们可以在错误返回中做同样的事情。如果出现以下情况,延迟将认为回调/错误返回失败:

  • 回调/错误返回引发任何类型的异常,或者
  • 回调/errback 返回一个 Failure 对象。

由于 errback 的第一个参数始终是 Failure,因此 errback 可以在执行它想要采取的任何操作后,通过返回其第一个参数来“重新引发”异常。

是的,刚刚尝试过,如果你改变:

def error(results):
  print 'error'
  return results

to

def error(results):
  print 'error'
  return

您不会重新引发错误状态,因此它不会渗透回反应器,也不会导致让您烦恼的回溯。

附:我不能推荐krondo的扭曲简介 http://krondo.com/blog/?p=1209足够的!它可能真的很长,但如果你能通过它,你真的将能够以扭曲的方式生成代码,并且这些行为将不再是一个谜。

P.P.S 我看到你之前有这样的问题(当 deferreds 引发错误时,Python DeferredList 回调报告成功 https://stackoverflow.com/questions/23351538/python-deferredlist-callback-reporting-success-when-deferreds-raise-error)关于延迟的,这可能是您以这种方式构建代码的原因。我认为您可能对 def 涉及 deferreds (特别是 errbacks)的返回值/回调值有一个根本性的误解。查看part 9 http://krondo.com/blog/?p=1825(尽管你可能需要备份part 7 http://krondo.com/blog/?p=1682或者甚至更早地跟踪它)krondo 的,它确实应该有助于解决问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何捕获源自reactor.stop()的Deferred中未处理的错误 的相关文章

随机推荐