Twisted的陷阱方法引发了不被捕获的异常

时间:2015-09-22 09:21:04

标签: python twisted

在我看来,似乎 failure.trap 方法正在引发无法用try / except块捕获的异常。

from twisted.internet import defer


def someAsynchronousMethod(_):
    print 'I am an asynchronous method and I raise a ZeroDivisionError!!!'
    raise ZeroDivisionError

def __errorHandler(failure):
    print 'I am __errorHandler number 1 !!!!'
    try:
        # Traps only NameError, other Errors will be immediately reraised
        failure.trap(NameError)

        # This code executes only if Exception has been trapped
        ret = {'errno': 666,
               'errmsg': 'NameError'
               }

    # It looks like this code will be executed if Exception has not been trapped
    # instead it was reraised and should be caught here, but it turns out it
    # doesn't get caught, instead the method returns None at this point
    except Exception:
        # This code is never reached
        ret = {'errno': 5000,
               'errmsg': 'OtherError'
               }

    # This code is reached if Exception has been trapped
    return ret

def __successHandler(result):
    print 'Successful execution !!!!'
    return result


def __successHandler2(result):
    print """I expect to receive ret = {'errno': 5000, 'errmsg': 'OtherError'},
          because __errorHandler number 1 is supposed to return a dict !!!!"""
    return result


def __errorHandler2(failure):
    print 'I am __errorHandler number 2 !!!!'
    return failure


d = defer.Deferred()

# Method that raises an Error
d.addCallback(someAsynchronousMethod)

d.addCallbacks(__successHandler, __errorHandler)

d.addCallbacks(__successHandler2, __errorHandler2)

d.callback(0)

输出:

I am an asynchronous method and I raise a ZeroDivisionError!!!
I am __errorHandler number 1 !!!!
I am __errorHandler number 2 !!!!
Unhandled error in Deferred:
Unhandled Error
Traceback (most recent call last):
  File "twistedFailures.py", line 58, in <module>
    d.callback(0)
  File "/usr/local/lib/python2.7/dist-packages/twisted/internet/defer.py", line 382, in callback
    self._startRunCallbacks(result)
  File "/usr/local/lib/python2.7/dist-packages/twisted/internet/defer.py", line 490, in _startRunCallbacks
    self._runCallbacks()
--- <exception caught here> ---
  File "/usr/local/lib/python2.7/dist-packages/twisted/internet/defer.py", line 577, in _runCallbacks
    current.result = callback(current.result, *args, **kw)
  File "twistedFailures.py", line 8, in someAsynchronousMethod
    raise ZeroDivisionError
exceptions.ZeroDivisionError: 

我预计无论 failure.trap 方法引发什么异常,它都会被捕获,但我错了。

有什么特定的Twisted在幕后处理这个吗?如果是,为什么和什么?

1 个答案:

答案 0 :(得分:0)

您希望failure.trap重新提升ZeroDivisionError例外。但这只发生在Python 3中:在Python 2中,failure.trap实际上重新引发了failuredocumentation对此很清楚:

  

在Python 2中,将提出失败;在Python 3中,将重新引发基础异常。

Twisted的Failure课程不会继承Exception,因此您的except Exception:无法抓住它。您需要except (Exception, Failure):代替。