我有以下课程:
class SessionHandler(tornado.websocket.WebSocketHandler):
@tornado.gen.coroutine
def on_message(self):
yield self.application.c.check("xxx@gmail.com")
check()函数类似于
@tornado.gen.coroutine
def check(self,id):
if id not in self.AUTH_METHOD.keys():
raise InvalidXX
InvalidXX
是一个用户定义的异常,它继承自Exception
类。
当引发此异常时,龙卷风控制台不会显示任何内容。但是,当我在它们周围添加try / except子句时,会拾取异常。我不明白为什么这个异常没有传播到控制台。其他例外例如MongoDB中的重复键被传播并显示在控制台中。
答案 0 :(得分:3)
[此答案适用于Tornado 4.4及更早版本。截至Tornado 4.5 on_message
可能是一个协程,原始问题中的代码可以正常工作]
与常规函数不同地调用协程(即必须使用yield
调用它们)。因此,当您定义一个框架调用的方法时,您应该只在文档说出&#34之类的东西时使用协程;这个方法可能是一个协程"。 WebSocketHandler.on_message
可能不是协程(截至Tornado 4.3)。
相反,您可以使用IOLoop.spawn_callback
从on_message
回调中启动独立协程。
def on_message(self, msg):
IOLoop.current().spawn_callback(process_message, msg)
@gen.coroutine
def process_message(self, msg):
...
这里的一个重要区别是spawn_callback
将协程与WebSocketHandler
中接收消息的代码分离:在第一个产生的回调之前,您可能会收到第二个on_message
调用完了。使用tornado.locks
和tornado.queues
模块中的方法来管理此并发。 (相比之下,在RequestHandler.data_received
中,哪个可能是一个协程,在第二个数据被处理之前,你不会获得第二个数据块,并且未捕获的异常将中止连接)