2010-09-27 98 views
5

我扭曲的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。任何想法可能會出錯?

回答

7

如果您沒有任何關於錯誤的其他提示(例如您的單元測試指出導致此問題的具體情況,或者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

2

我想你的代碼中的一些地方,你明確地調用了延期的回調。這也發生了多次。延遲迴調只能觸發一次,這表示完成了等待已久的任務,導致錯誤或肯定結果。 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 

查覈在你的代碼多次點火的可能性。這可能是問題。