扭曲如何摆脱Deferred中未处理的错误?

问题描述

我有一个deferredList会在第一个回调上触发,但是我实际上是在玩回调链的性质,因此,如果没有回调被触发,则将触发errbacks。

问题是,一旦我添加错误处理程序addErrback和我创建的Failure的处理程序,就会触发并且 stdout 仍然使我大喊: >

Unhandled error in Deferred:

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

在最终的错误回复中执行以下操作:

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

ALSO,每个都认为我在所有代码中都包含一个errback处理程序:

def onError(error):
    return error

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

解决方法

consumeErrors=True传递到您的DeferredList结构中。

您正在使用以下创建的延迟填充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错误是禁止操作的。它接受一个错误,然后传播它。 dd.addErrback(onError)的行为将完全相同。如果要消除错误,则必须重新引发它或将其返回。

DeferredList(consumeErrors=True)有效的作用是使DeferredList添加类似以下内容的错误提示:

def onError(reason):
    return None

每个递延。 you 不想对每个urlFire推迟这样做的原因是,它等效于“ except:pass”。它将抑制所有来自这些延期的错误。这样甚至可以防止DeferredList对它们执行任何操作。 DeferredList(consumeErrors=True)确保错误在其他地方传播,因此最好在各个Deferred上抑制它们。