【问题标题】:Can Deferred.callback() or Deferred.errback() raise an exception to the caller?Deferred.callback() 或 Deferred.errback() 可以向调用者引发异常吗?
【发布时间】:2014-03-11 15:05:35
【问题描述】:

是否存在调用.callback().errback() 会向调用者引发异常而不会被延迟函数捕获的情况?

假设我有以下延迟和回调:

from twisted.internet import defer

def bad_callback(result):
    raise Exception()

def bad_errback(result):
    raise Exception()

d = defer.Deferred()
d.addCallbacks(bad_callback, bad_errback)

如果我调用d.callback(None)d 中的结果将是来自bad_callback()Exception。如果我调用d.errback(Exception())d 中的结果将是从bad_errback() 引发的Exception。但是,在任何一种情况下,都不会向调用者提出异常。

现在,我确实知道调用 .callback().errback() 会向调用者引发异常的几种情况,但这些情况会违反正确使用延迟。

  • 显然,如果您使用不正确数量的参数调用 .callback().errback(),它将引发 TypeError

  • 调用已调用的 deferred 将引发 AlreadyCalledError

  • 调用.callback(defer.Deferred()) 将引发AssertionError

  • 调用.errback() 等效于调用.errback(failure.Failure()),如果没有活动异常,则会引发NoCurrentExceptionError

真的,我的问题归结为:只要尚未调用 deferred 并且结果正确,我是否可以安全地依赖调用 .callback(result).errback(exception_or_failure) 的结果永远不会引发异常的行为?

【问题讨论】:

    标签: python twisted twisted.internet


    【解决方案1】:

    我运行了您的示例,在底部添加了两行:

    d.callback(None)
    print("OK!")
    

    得到这个输出:

    Unhandled error in Deferred:
    Unhandled Error
    Traceback (most recent call last):
      File "callbacks.py", line 11, in <module>
        d.callback(None)
      File ".../twisted/internet/defer.py", line 368, in callback
        self._startRunCallbacks(result)
      File ".../twisted/internet/defer.py", line 464, in _startRunCallbacks
        self._runCallbacks()
    --- <exception caught here> ---
      File ".../twisted/internet/defer.py", line 551, in _runCallbacks
        current.result = callback(current.result, *args, **kw)
      File "callbacks.py", line 4, in bad_callback
        raise Exception()
    exceptions.Exception: 
    OK!
    

    因此,在这种特定情况下(如您自己确定的那样),不,不会重新引发异常。

    在一般情况下,有几个地方异常会有效传播出去;如果你有一个MemoryError,因为你完全内存不足,那么Deferred 实现本身很可能会通过尝试调用函数或其他东西在某处分配一点内存,并且该异常会返回给你。

    但这只是在一般情况下使用 Python 编程的风险;有几个例外(MemoryErrorKeyboardInterrupt)可能会在没有警告的情况下出现。如果您的整个过程没有烧毁,那么不,callbackerrback 不会引发异常,除非您列出的情况除外。

    【讨论】:

      猜你喜欢
      • 2014-07-29
      • 2015-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-05
      • 2015-08-14
      相关资源
      最近更新 更多