Twisted Deferred 在没有 errback 的情况下不显示未处理的异常
Twisted Deferred not displaying unhandled Exception without errback
我正在阅读 McKellar 和 Fettig 的 Twisted Network Programming Essentials, 2nd Ed.
我在 运行宁 Twisted 15.5.0 Python 2.7.10 Windows 7.
在关于 Deferred
的部分中,有一个示例应该引发 Unhandled Error in Deferred
- 但是当我 运行 下面的最小示例时,我只是从控制台获得完全的静音:
最小示例
from twisted.internet.defer import Deferred
def raiseErr(err):
raise Exception(err)
d = Deferred()
d.addCallback(raiseErr)
d.callback("oh no")
$ python test.py
(no output)
实际书籍文本中的最小示例
书中的实际例子是这样的:
from twisted.internet.defer import Deferred
def callback1(result):
print "Callback 1 said:", result
return result
def callback2(result):
print "Callback 2 said:", result
def callback3(result):
raise Exception("Callback 3")
def errback1(failure):
print "Errback 1 had an an error on", failure
return failure
d = Deferred()
d.addCallback(callback1)
d.addCallback(callback2)
d.addCallback(callback3)
d.callback("Test")
预期输出在书中列为:
callback3
raises an Exception
, and because there is no registered errback
to handle the Exception
, the program terminates and reports an Unhandled Error
to the user. The result is:
Callback 1 said: Test
Callback 2 said: Test
Unhandled error in Deferred:
Unhandled Error
Traceback (most recent call last):
File "/tmp/test.py", line 33, in <module>
d.callback("Test")
<...>
File "/tmp/test.py", line 11, in callback3
raise Exception("Callback 3")
exceptions.Exception: Callback 3
我是不是做错了什么?
编辑:
我遇到了在我的机器上正确显示的错误。
为了在 Deferred
object 上没有 errback
处理程序的情况下记录错误,我需要将以下内容添加到我的代码片段中:
import sys
from twisted.python import log
log.startLogging(sys.stdout)
# rest of the code goes here
现在,当我 运行 来自问题中第一个代码片段的最小示例时,我得到以下输出:
2016-02-05 09:45:43-0600 [-] Log opened.
2016-02-05 09:45:43-0600 [-] Invalid format string or unformattable object in log message: '%(log_legacy)s', {'format': '%(log_legacy)s', 'log_legacy': <twisted.logger._stdlib.StringifiableFromEvent object at 0x038913F0>, 'time': 1454687143.778, 'message': (), 'log_time': 1454687143.778, 'log_namespace': 'twisted.internet.defer', 'log_level': <LogLevel=critical>, 'log_source': None, 'system': '-', 'isError': True, 'log_logger': <Logger 'twisted.internet.defer'>, 'log_format': 'Unhandled error in Deferred:'}
2016-02-05 09:45:43-0600 [-] Unhandled Error
Traceback (most recent call last):
File "testd.py", line 13, in <module>
d.callback("oh no")
File "C:\Swat\.virtualenvs\twisted\lib\site-packages\twisted\internet\defer.py", line 393, in callback
self._startRunCallbacks(result)
File "C:\Swat\.virtualenvs\twisted\lib\site-packages\twisted\internet\defer.py", line 501, in _startRunCallbacks
self._runCallbacks()
--- <exception caught here> ---
File "C:\Swat\.virtualenvs\twisted\lib\site-packages\twisted\internet\defer.py", line 588, in _runCallbacks
current.result = callback(current.result, *args, **kw)
File "testd.py", line 9, in raiseErr
raise Exception(err)
exceptions.Exception: oh no
所以,现在我可以验证 Twisted 确实会按预期引发错误 - 只是出于某种原因不想告诉我。如果有人可以详细说明为什么在没有定义 errback 的情况下处理异常的默认情况,我很想知道。
我更改了标题以反映我的新问题。
我认为我们的代码没有任何问题。
我在这里试过运行:
$ python deferred.py
输出为:
Unhandled error in Deferred:
Traceback (most recent call last):
File "deferred.py", line 8, in <module>
d.callback("oh no")
File "/home/vagrant/.virtualenvs/asyncproxy/local/lib/python2.7/site-packages/twisted/internet/defer.py", line 393, in callback
self._startRunCallbacks(result)
File "/home/vagrant/.virtualenvs/asyncproxy/local/lib/python2.7/site-packages/twisted/internet/defer.py", line 501, in _startRunCallbacks
self._runCallbacks()
--- <exception caught here> ---
File "/home/vagrant/.virtualenvs/asyncproxy/local/lib/python2.7/site-packages/twisted/internet/defer.py", line 588, in _runCallbacks
current.result = callback(current.result, *args, **kw)
File "deferred.py", line 4, in raiseErr
raise Exception(err)
exceptions.Exception: oh no
我正在使用 Twisted 15.5.0 和 Python 2.7.6.
P.S: 没有必要初始化日志。没有它也能工作。
此代码在我测试过的所有 Windows 机器和 Linux 机器的 none 上给出了相同的结果。我得出的结论是,这是与 Windows、twisted 或 pywin32 有关的问题。
我在研究 Dave Perticola 的优秀文章 Twisted Introduction specifically in Part 9: A Second Interlude, Deferred he has an example 时遇到了一个非常相似的问题后发现了这个问题,与您发布的问题相似:
from twisted.internet.defer import Deferred
def callback(res):
raise Exception('oops')
d = Deferred()
d.addCallback(callback)
d.callback('Here is your result.')
print "Finished"
就像你一样,我没有得到建议的输出:
Finished
Unhandled error in Deferred:
Traceback (most recent call last):
...
--- <exception caught here> ---
...
exceptions.Exception: oops
我最初认为是版本控制问题,对我来说是在 EL6 上使用 PyPy 5.0.1 的 Twisted 16,但研究将我带到了这里;然后按照另一个答案中的建议打开日志记录时,对我认为的实际答案没有影响。
我的答案的线索是在我正在使用的教程中,声明如下:
the reason that “Finished” comes first is because the “Unhandled” message isn’t actually printed until the deferred is garbage collected.
出于某种原因,对于你我来说,当垃圾收集器开始做它的事情时,它已经没有地方可以输出了。如果你想看看这是真的,这是我修改后的代码:
import gc
from twisted.internet.defer import Deferred
def callback(res):
raise Exception('oops call')
d = Deferred()
d.addCallback(callback)
d.callback('Here is your result.')
d = None
gc.collect()
print "Finished"
我想真正的答案是在垃圾收集器到达之前处理您的异常,但也许这些信息会让您睡得更轻松,即使我们不知道为什么它对某些人有用,我们知道是什么导致我们预期的错误消息消失。
我正在阅读 McKellar 和 Fettig 的 Twisted Network Programming Essentials, 2nd Ed.
我在 运行宁 Twisted 15.5.0 Python 2.7.10 Windows 7.
在关于 Deferred
的部分中,有一个示例应该引发 Unhandled Error in Deferred
- 但是当我 运行 下面的最小示例时,我只是从控制台获得完全的静音:
最小示例
from twisted.internet.defer import Deferred
def raiseErr(err):
raise Exception(err)
d = Deferred()
d.addCallback(raiseErr)
d.callback("oh no")
$ python test.py
(no output)
实际书籍文本中的最小示例
书中的实际例子是这样的:
from twisted.internet.defer import Deferred
def callback1(result):
print "Callback 1 said:", result
return result
def callback2(result):
print "Callback 2 said:", result
def callback3(result):
raise Exception("Callback 3")
def errback1(failure):
print "Errback 1 had an an error on", failure
return failure
d = Deferred()
d.addCallback(callback1)
d.addCallback(callback2)
d.addCallback(callback3)
d.callback("Test")
预期输出在书中列为:
callback3
raises anException
, and because there is no registerederrback
to handle theException
, the program terminates and reports anUnhandled Error
to the user. The result is:
Callback 1 said: Test
Callback 2 said: Test
Unhandled error in Deferred:
Unhandled Error
Traceback (most recent call last):
File "/tmp/test.py", line 33, in <module>
d.callback("Test")
<...>
File "/tmp/test.py", line 11, in callback3
raise Exception("Callback 3")
exceptions.Exception: Callback 3
我是不是做错了什么?
编辑:
我遇到了在我的机器上正确显示的错误。
为了在 Deferred
object 上没有 errback
处理程序的情况下记录错误,我需要将以下内容添加到我的代码片段中:
import sys
from twisted.python import log
log.startLogging(sys.stdout)
# rest of the code goes here
现在,当我 运行 来自问题中第一个代码片段的最小示例时,我得到以下输出:
2016-02-05 09:45:43-0600 [-] Log opened.
2016-02-05 09:45:43-0600 [-] Invalid format string or unformattable object in log message: '%(log_legacy)s', {'format': '%(log_legacy)s', 'log_legacy': <twisted.logger._stdlib.StringifiableFromEvent object at 0x038913F0>, 'time': 1454687143.778, 'message': (), 'log_time': 1454687143.778, 'log_namespace': 'twisted.internet.defer', 'log_level': <LogLevel=critical>, 'log_source': None, 'system': '-', 'isError': True, 'log_logger': <Logger 'twisted.internet.defer'>, 'log_format': 'Unhandled error in Deferred:'}
2016-02-05 09:45:43-0600 [-] Unhandled Error
Traceback (most recent call last):
File "testd.py", line 13, in <module>
d.callback("oh no")
File "C:\Swat\.virtualenvs\twisted\lib\site-packages\twisted\internet\defer.py", line 393, in callback
self._startRunCallbacks(result)
File "C:\Swat\.virtualenvs\twisted\lib\site-packages\twisted\internet\defer.py", line 501, in _startRunCallbacks
self._runCallbacks()
--- <exception caught here> ---
File "C:\Swat\.virtualenvs\twisted\lib\site-packages\twisted\internet\defer.py", line 588, in _runCallbacks
current.result = callback(current.result, *args, **kw)
File "testd.py", line 9, in raiseErr
raise Exception(err)
exceptions.Exception: oh no
所以,现在我可以验证 Twisted 确实会按预期引发错误 - 只是出于某种原因不想告诉我。如果有人可以详细说明为什么在没有定义 errback 的情况下处理异常的默认情况,我很想知道。
我更改了标题以反映我的新问题。
我认为我们的代码没有任何问题。
我在这里试过运行:
$ python deferred.py
输出为:
Unhandled error in Deferred:
Traceback (most recent call last):
File "deferred.py", line 8, in <module>
d.callback("oh no")
File "/home/vagrant/.virtualenvs/asyncproxy/local/lib/python2.7/site-packages/twisted/internet/defer.py", line 393, in callback
self._startRunCallbacks(result)
File "/home/vagrant/.virtualenvs/asyncproxy/local/lib/python2.7/site-packages/twisted/internet/defer.py", line 501, in _startRunCallbacks
self._runCallbacks()
--- <exception caught here> ---
File "/home/vagrant/.virtualenvs/asyncproxy/local/lib/python2.7/site-packages/twisted/internet/defer.py", line 588, in _runCallbacks
current.result = callback(current.result, *args, **kw)
File "deferred.py", line 4, in raiseErr
raise Exception(err)
exceptions.Exception: oh no
我正在使用 Twisted 15.5.0 和 Python 2.7.6.
P.S: 没有必要初始化日志。没有它也能工作。
此代码在我测试过的所有 Windows 机器和 Linux 机器的 none 上给出了相同的结果。我得出的结论是,这是与 Windows、twisted 或 pywin32 有关的问题。
我在研究 Dave Perticola 的优秀文章 Twisted Introduction specifically in Part 9: A Second Interlude, Deferred he has an example 时遇到了一个非常相似的问题后发现了这个问题,与您发布的问题相似:
from twisted.internet.defer import Deferred
def callback(res):
raise Exception('oops')
d = Deferred()
d.addCallback(callback)
d.callback('Here is your result.')
print "Finished"
就像你一样,我没有得到建议的输出:
Finished
Unhandled error in Deferred:
Traceback (most recent call last):
...
--- <exception caught here> ---
...
exceptions.Exception: oops
我最初认为是版本控制问题,对我来说是在 EL6 上使用 PyPy 5.0.1 的 Twisted 16,但研究将我带到了这里;然后按照另一个答案中的建议打开日志记录时,对我认为的实际答案没有影响。
我的答案的线索是在我正在使用的教程中,声明如下:
the reason that “Finished” comes first is because the “Unhandled” message isn’t actually printed until the deferred is garbage collected.
出于某种原因,对于你我来说,当垃圾收集器开始做它的事情时,它已经没有地方可以输出了。如果你想看看这是真的,这是我修改后的代码:
import gc
from twisted.internet.defer import Deferred
def callback(res):
raise Exception('oops call')
d = Deferred()
d.addCallback(callback)
d.callback('Here is your result.')
d = None
gc.collect()
print "Finished"
我想真正的答案是在垃圾收集器到达之前处理您的异常,但也许这些信息会让您睡得更轻松,即使我们不知道为什么它对某些人有用,我们知道是什么导致我们预期的错误消息消失。