如何在Deferred中捕获来自react.stop()的未处理错误 [英] How to catch unhandled error in Deferred originating from reactor.stop()

查看:61
本文介绍了如何在Deferred中捕获来自react.stop()的未处理错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是新手,对以下脚本有麻烦.

I am new to twisted and having trouble with the following script.

当我运行以下命令时:

#!/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.

我的问题是,当我似乎在错误回调中捕获到错误时,为什么会得到未处理的错误?

My question is why am I getting an unhandled error when I seem to have caught the error with my error callback?

推荐答案

问题是,在您的 error def中,您会返回 result ,在给定的情况下,错误返回是 Failure 对象,而返回 Failure 对象是重新引发错误状态的两个条件之一.请参见 krondo的简介-第9部分中的以下内容:

The problem is that in your error def you return result which, given it was called by an error back is a Failure object, and returning a Failure object is one of the two criteria for re-raising the error state. See the following blurb from krondo's twisted intro - part 9:

现在,在同步代码中,我们可以使用不带任何参数的raise关键字重新引发"异常.这样做会引发我们正在处理的原始异常,并允许我们对错误采取某些措施而没有完全处理它.事实证明,我们可以在犯错时做同样的事情.如果出现以下情况,则推迟的人将认为回调/错误返回失败:

Now, in synchronous code we can "re-raise" an exception using the raise keyword without any arguments. Doing so raises the original exception we were handling and allows us to take some action on an error without completely handling it. It turns out we can do the same thing in an errback. A deferred will consider a callback/errback to have failed if:

  • 回调/错误返回引发任何异常,或者
  • 回调/错误返回一个故障对象.

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

Since an errback’s first argument is always a Failure, an errback can "re-raise" the exception by returning its first argument, after performing whatever action it wants to take.

是的,如果您进行了更改,请尝试一下:

Yup, just tried it, if you change:

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

def error(results):
  print 'error'
  return

您不会重新引发错误状态,因此它不会渗透回反应堆,也不会引起令人讨厌的回溯.

You won't re-raise the error state, so it won't percolate back to the reactor, and won't cause the traceback thats annoying you.

P.S.我不能推荐足够足够的 krondo的扭曲介绍!可能确实很长,但是如果您能克服它,您实际上将能够产生扭曲的代码,而这种行为将不是一个谜.

P.S. I can't recommend krondo's twisted introduction enough! It may be really long but if you can get through it, you really will be able to produce code in twisted and these sort of behaviors won't be a mystery.

PPS我看到您之前有一个SO问题( Python DeferredList延迟时引发回调报告成功)有关延迟的错误,这可能是您以这种方式构建代码的原因.我认为您可能对def所涉及的def的返回值/回调值(尤其是errback)有根本的误解.查看第9部分(尽管您可能必须备份

P.P.S I see you have previous SO question (Python DeferredList callback reporting success when deferreds raise error) about deferred's that might be the reason you built the code this way. I think you may have a fundamental misunderstanding about the return-value/callback-value of def's involved in deferreds (particularly errbacks). Check out part 9 (though you might have to backup part 7 or even earlier to track it) of krondo's, it really should help clear things up.

这篇关于如何在Deferred中捕获来自react.stop()的未处理错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆