2015-09-22 55 views
2

在我看來,好像failure.trap方法引發了無法用try/except塊捕獲的異常。Twisted的陷阱方法引發了不被捕獲的異常

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) 

OUTPUT:

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在幕後處理這件事有什麼具體的嗎?如果是的話,爲什麼和什麼?

回答

0

您期待failure.trap重新提高ZeroDivisionError例外。但是這隻發生在Python 3中:在Python 2中,failure.trap實際上會重新提高failuredocumentation對此很清楚:

在Python 2中會失敗;在Python 3中,基礎異常將被重新提出。

Twisted的Failure類不從Exception繼承所以你except Exception:不抓住它。您需要改爲except (Exception, Failure):