扭曲:无益“AlreadyCalled”错误

扭曲:无益“AlreadyCalled”错误

问题描述:

我扭曲的Python程序不断以往经常喷涌此消息:扭曲:无益“AlreadyCalled”错误

Unhandled error in Deferred: 

Traceback (most recent call last): 
    File "c:\python25\lib\site-packages\twisted\internet\defer.py", line 757, in gotResult 
    _inlineCallbacks(r, g, deferred) 
    File "c:\python25\lib\site-packages\twisted\internet\defer.py", line 747, in _inlineCallbacks 
    deferred.errback() 
    File "c:\python25\lib\site-packages\twisted\internet\defer.py", line 269, in errback 
    self._startRunCallbacks(fail) 
    File "c:\python25\lib\site-packages\twisted\internet\defer.py", line 312, in _startRunCallbacks 
    self._runCallbacks() 
--- <exception caught here> --- 
    File "c:\python25\lib\site-packages\twisted\internet\defer.py", line 328, in _runCallbacks 
    self.result = callback(self.result, *args, **kw) 
    File "c:\python25\lib\site-packages\twisted\internet\defer.py", line 243, in callback 
    self._startRunCallbacks(result) 
    File "c:\python25\lib\site-packages\twisted\internet\defer.py", line 298, in _startRunCallbacks 
    raise AlreadyCalledError 
twisted.internet.defer.AlreadyCalledError: 

这不是太大的帮助,因为它没有提到我的源代码...我也正好正在使用defer.inlineCallbacks。任何想法可能会出错?

如果您没有任何关于错误的其他提示(例如您的单元测试指出导致此问题的具体情况,或者pyfunc的答案没有明确说明为什么会发生这种情况),则启用延迟调试以获得有关被指定的递延的第一个(也是唯一允许的)结果,其中信息:

from twisted.internet import defer 
defer.setDebugging(True) 

或者

twistd --debug [...] 

或者

trial --debug [...] 

你会得到额外的堆栈跟踪错误报告,像你遇到过的。额外的堆栈跟踪会告诉你在什么地方创建了Deferred,以及它在哪里被首次调用(对它调用了.callback()或.errback())。

由于您使用的是inlineCallbacks,因此您无法获得有关发生实际错误的位置的良好堆栈跟踪信息,但关于Deferred第一次触发位置的信息可能会提供有关后续激活可能发生的位置的提示从。

不幸的是,增加的默认值仅仅是使用inlineCallbacks的成本。这可能是可以克服的,但有人需要承担这一任务。

+0

这似乎有帮助。我刚刚解雇了一个错误,至少能告诉我延期的创建地点,这很有帮助 – Claudiu 2010-09-28 22:27:09

我想你的代码中的一些地方,你明确地调用了延期的回调。这也发生了多次。延迟回调只能触发一次,这表示完成了等待已久的任务,导致错误或肯定结果。 Twisted有一种机制来抛出上述异常,如果你试图不止一次地推迟延迟。

考虑下面的代码:

from twisted.internet.defer import Deferred 
def func(x): print x 
d = Deferred() 
d.addCallbacks(func, func) 
d.callback('First fire') 
d.callback('Second fire') 

这将导致以下错误:

raise AlreadyCalledError 
twisted.internet.defer.AlreadyCalledError 

查核在你的代码多次点火的可能性。这可能是问题。