扭曲未处理的错误

时间:2011-08-05 21:16:14

标签: python twisted reactor twisted.internet

当扭曲的电抗器运行并且在未捕获的延迟内发生异常时,“未处理的错误”将与回溯和异常一起打印到终端。是否可以处理/拦截这些异常(例如,设置回调或覆盖方法)?

编辑:我知道我可以通过向deferrerd添加错误来捕获失败。我想知道的是,是否有办法拦截一条未经处理的失败/异常,这条失败/异常已经越过链条进入反应堆。

编辑:基本上,我想知道扭曲的反应堆是否有一个全局错误处理程序或可以访问的东西。我想知道因为它打印了故障中的追溯和错误。

示例:

Unhandled Error
Traceback (most recent call last):
  File "/var/projects/python/server.py", line 359, in run_server
    return server.run()
  File "/var/projects/python/server.py", line 881, in run
    reactor.run()
  File "/usr/local/lib/python2.6/dist-packages/Twisted-11.0.0-py2.6-linux-x86_64.egg/twisted/internet/base.py", line 1162, in run
    self.mainLoop()
  File "/usr/local/lib/python2.6/dist-packages/Twisted-11.0.0-py2.6-linux-x86_64.egg/twisted/internet/base.py", line 1171, in mainLoop
    self.runUntilCurrent()
--- <exception caught here> ---
  File "/usr/local/lib/python2.6/dist-packages/Twisted-11.0.0-py2.6-linux-x86_64.egg/twisted/internet/base.py", line 793, in runUntilCurrent
    call.func(*call.args, **call.kw)
  File "/var/projects/python/server.py", line 524, in monitor
    elapsed = time.time() - info.last
exceptions.NameError: global name 'info' is not defined

3 个答案:

答案 0 :(得分:6)

因为这些回溯是使用对twisted.python.log.deferr()的调用(无论如何在Twisted 10.2中)编写的,所以可以使用日志观察器重定向它们。这是这些堆栈跟踪最常见的事情。我找不到日志观察者的任何基类(令人惊讶),但内置了几个:

twisted.python.log.PythonLoggingObserver - 记录的任何内容都会转到标准的Python logging模块。 (我在我的申请中使用它。)

twisted.python.log.FileLogObserver - 记录的任何内容都会转到文件中。

这两个都会捕获反应堆报告的堆栈痕迹。您所要做的就是构造日志观察者(无参数),然后调用对象的start()方法。

(旁注:如果您愿意,还可以构建StdioOnnaStick课程并分配给sys.stdoutsys.stderr。然后您print转到Twisted日志。)

真的,真的拦截这些调用,所以堆栈跟踪永远不会被记录,你可以:

  • 子类twisted.internet.SelectReactor并覆盖其runUntilCurrent()方法。这就是记录堆栈跟踪的内容。在执行此操作之前,您需要研究twisted.internet.base.ReactorBase的来源。
  • 完成所有twisted.*次导入后,将twisted.python.log.deferr设置为您选择的函数,该函数与原型def err(_stuff=None, _why=None, **kw)兼容。

答案 1 :(得分:3)

您可以向延迟添加错误;未处理的异常会自动转换为twisted.python.failure.Failure

答案 2 :(得分:1)

回答你的评论:

  

基本上,我想知道扭曲的反应堆是否有全局错误处理程序或可以访问的东西。我想知道因为它打印了故障中的追溯和错误。

回应“不合适”。

首先,反应堆与延迟无关,实际上,整个延迟模块应放在twisted.python包中,但由于某些依赖性,这还不能完成。回到你的问题......

深入研究扭曲的代码(更准确,twisted.internet.defer模块),您可以概述以下事件流程:

  1. 当使用结果调用callback方法时,延迟实例开始通过_runCallbacks方法运行其回调;
  2. 如果其中一个回调引发异常,则会将其包装为失败(行542);
  3. 如果回调链用尽且最后一个结果失败,则将当前结果分配给DebugInfo实例的failResult属性(行575);
  4. 如果延迟实例及其DebugInfo实例被垃圾收集,结果仍然存在活动失败,则调用DebugInfo.__del__方法并打印回溯。
  5. 鉴于这些前提,最简单的解决方案之一就是修补DebugInfo类:

    from twisted.internet.defer import DebugInfo
    del DebugInfo.__del__  # Hides all errors