Tornado WebSocket on_message 方法中的异常被忽略
Exception ignored in Tornado WebSocket on_message method
我有以下 class:
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
class.
的用户定义异常
引发此异常时,Tornado 控制台不会显示任何内容。但是,当我在它们周围添加 try/except 子句时,会发现异常。我不明白为什么没有将此异常传播到控制台。其他例外MongoDB 中的重复键被传播并显示到控制台。
[此答案适用于 Tornado 4.4 及更早版本。从 Tornado 4.5 开始,on_message
可能是协程,原始问题中的代码将起作用]
协程的调用方式与常规函数不同(即它们必须使用 yield
调用)。因此,当您定义要由框架调用的方法时,您应该只在文档说 "this method may be a coroutine" 时才使用协程。 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
中, 可能 是协程,在处理第二个数据块之前,您不会获得第二个数据块,并且未捕获的异常将中止连接)
我有以下 class:
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
class.
引发此异常时,Tornado 控制台不会显示任何内容。但是,当我在它们周围添加 try/except 子句时,会发现异常。我不明白为什么没有将此异常传播到控制台。其他例外MongoDB 中的重复键被传播并显示到控制台。
[此答案适用于 Tornado 4.4 及更早版本。从 Tornado 4.5 开始,on_message
可能是协程,原始问题中的代码将起作用]
协程的调用方式与常规函数不同(即它们必须使用 yield
调用)。因此,当您定义要由框架调用的方法时,您应该只在文档说 "this method may be a coroutine" 时才使用协程。 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
中, 可能 是协程,在处理第二个数据块之前,您不会获得第二个数据块,并且未捕获的异常将中止连接)