问题描述
我有一个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
错误是禁止操作的。它接受一个错误,然后传播它。 d
和d.addErrback(onError)
的行为将完全相同。如果要消除错误,则必须不重新引发它或将其返回。
DeferredList(consumeErrors=True)
有效的作用是使DeferredList
添加类似以下内容的错误提示:
def onError(reason):
return None
每个递延。 you 不想对每个urlFire
推迟这样做的原因是,它等效于“ except:pass”。它将抑制所有来自这些延期的错误。这样甚至可以防止DeferredList
对它们执行任何操作。 DeferredList(consumeErrors=True)
确保错误在其他地方传播,因此最好在各个Deferred上抑制它们。