扭曲:无益“AlreadyCalled”错误

时间:2010-09-27 20:39:28

标签: python debugging twisted

我扭曲的python程序经常不停地喷出这条消息:

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。知道可能出了什么问题吗?

2 个答案:

答案 0 :(得分:7)

如果你没有任何关于出错的其他提示(比如你的单元测试指出导致这种情况的特定情况,或者如果pyfunc的答案没有明确说明为什么会发生这种情况),那么启用延迟调试获取有关指定Deferred的第一个(也是唯一允许的)结果的位置的信息:

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

或者

twistd --debug [...]

或者

trial --debug [...]

您将获得额外的堆栈跟踪,其中包含您遇到的错误报告。额外的堆栈跟踪将告诉您创建的Deferred的位置以及首次调用它的位置(调用了.callback()或.errback())。

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

不幸的是,增加的默默无闻仅仅是目前使用inlineCallbacks的成本。这可能是可以克服的,但有人需要承担这项任务。

答案 1 :(得分:2)

我想在你的代码中,你明确地调用了deferred的回调。这也发生了多次。延迟回调只能触发一次,表示期待已久的任务完成,导致错误或肯定结果。如果您尝试多次触发延迟,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

在您的代码中查看此类多次解雇的可能性。这可能是个问题。