【发布时间】:2016-08-11 14:25:35
【问题描述】:
我有一个使用 Tornado 的场景,其中我有一个从非协程调用或没有产生的协程,但我需要将异常传播回来。
想象以下方法:
@gen.coroutine
def create_exception(with_yield):
if with_yield:
yield exception_coroutine()
else:
exception_coroutine()
@gen.coroutine
def exception_coroutine():
raise RuntimeError('boom')
def no_coroutine_create_exception(with_yield):
if with_yield:
yield create_exception(with_yield)
else:
create_exception(with_yield)
调用:
try:
# Throws exception
yield create_exception(True)
except Exception as e:
print(e)
将正确引发异常。但是,以下均未引发异常:
try:
# none of these throw the exception at this level
yield create_exception(False)
no_coroutine_create_exception(True)
no_coroutine_create_exception(False)
except Exception as e:
print('This is never hit)
后者是类似于我的问题的变体 - 我有不受控制的代码调用协程而不使用 yield。在某些情况下,它们本身并不是协程。无论哪种情况,这意味着它们生成的任何异常都会被吞噬,直到 Tornado 将它们作为“未收到未来异常”返回。
这与 Tornado 的意图完全相反,他们的文档基本上表明您需要在整个堆栈中执行 yield/coroutine 才能使其按照我想要的方式工作,而无需黑客/诡计。
我可以更改引发异常的方式(即修改exception_coroutine)。但是我不能改变几个中间方法。
我可以做些什么来强制在整个 Tornado 堆栈中引发异常,即使它没有正确产生?基本上是在最后三种情况下正确引发异常?
这很复杂,因为我无法更改导致这种情况的代码。我只能在上面更改exception_coroutine。
【问题讨论】:
-
两个问题。首先,你能举一个例子或调用代码的草图吗?我很难理解你的意图。其次,您是否希望调用方阻塞直到协程完成(正常或通过引发异常)?
-
@A.JesseJiryuDavis 上面的存根函数反映了它是如何被调用的。关于 2,请参阅我的编辑 - 我想在我的 try/except 中查看异常。
标签: python python-2.7 asynchronous tornado