【问题标题】:Twisted how to get rid of Unhandled error in Deferred?Twisted 如何摆脱 Deferred 中的 Unhandled 错误?
【发布时间】:2020-12-17 12:13:37
【问题描述】:

我有一个 deferredList 会在第一次回调时触发,但我实际上是在玩回调链的性质,所以如果没有触发任何回调,则会触发 errbacks。

问题是,一旦我为 errbacks 添加处理程序,addErrback 和我创建的 Failure,触发器和 stdout 仍然对我大喊:

Unhandled error in Deferred:

Traceback (most recent call last):
Failure: __main__.notFound: Match not found!

最后的 errback 执行以下操作:

def emptyQuery(error, name):
    errorType = error.trap(notFound)
    if errorType == notFound:
        print("[-] Item not found in given sources: {name}".format(name=name))
    print("->", errorType)
    return

因此,

[(False, <twisted.python.failure.Failure __main__.notFound: Match not found!>)]
[-] Item not found for current sources: GIA-S12
-> <class '__main__.notFound'>
Unhandled error in Deferred:

Traceback (most recent call last):
Failure: __main__.notFound: Match not found!

我怎样才能摆脱那个“未处理的东西”?我陷入了错误,我不知道为什么它会这样大喊大叫。

它实际上是由我实现的这个for循环触发的:

for item in items:
        name, price = item
        itemQuery_deferreds = []
        for urlObject in URLS:
            urlFire = poolsem.acquire().addCallback(initQuery, urlObject.url, name, googleClient)
            itemQuery_deferreds.append(urlFire)
        itemQuery = DeferredList(itemQuery_deferreds, fireOnOneCallback=True)
        itemQuery.addCallback(parseData)
        itemQuery.addErrback(emptyQuery, name)

当然,在去 errback 处理程序 emptyQuery 之前,我必须期待回调首先被调用:

def parseData(data):
    print(data)
    for code, status in data:
        if not code:
            return status
        else:
            store = status

另外,每个我在所有代码中的延迟都包含一个 errback 处理程序:

def onError(error):
    return error

注意:我发现这很难调试,如果您需要更多信息,请尽管询问。

【问题讨论】:

    标签: python-3.x callback twisted deferred


    【解决方案1】:

    consumeErrors=True 传递给您的DeferredList 构造。

    您正在使用创建的 Deferred 填充 DeferredList

    urlFire = poolsem.acquire().addCallback(initQuery, urlObject.url, name, googleClient)
    

    如果urlFire 曾经失败过,那么DeferredList 会观察到这个失败并使其在自己的结果中可用。如果您没有通过 consumeErrors=True,则 DeferredList 确保 urlFire 保留其失败结果。如果您确实通过了consumeErrors=True,那么DeferredList 会将其元素上的任何故障转换为None

    另外,我在所有代码中的每个 Deferred 都包含一个 errback 处理程序:

    def onError(error):
       return error
    

    这没有任何意义。这个onError errback 是无操作的。它接受一个错误,然后传播它。 dd.addErrback(onError) 的行为方式完全相同。如果你想摆脱一个错误,你必须重新提出或返回它。

    DeferredList(consumeErrors=True) 的实际作用是让DeferredList 添加一个 errback,例如:

    def onError(reason):
        return None
    

    到每个延迟。 不想对你所做的每个urlFire Deferred 执行此操作的原因是它相当于“除了:通过”。它将抑制来自这些 Deferred 的所有错误。这甚至会阻止DeferredList 对他们做任何事情。 DeferredList(consumeErrors=True) 确保错误在其他地方传播,因此可以在单个 Deferred 上抑制它们。

    【讨论】:

    • 谢谢!那么让 DeferredLists 以这种方式大喊大叫有什么意义呢?同样来自扭曲的文档“使用此选项在 DeferredList 中停止错误将防止来自它包含的 Deferreds 中的“未处理的错误”警告,而无需添加额外的 errbacks”。 “无需添加额外的错误提示”我什至无法添加额外的错误提示并删除此错误,所以我不确定为什么有人想要这个?
    • 哦,实际上是从您指出的最后一段中得到的!再次感谢您说得足够清楚!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多