在Tornado WebSocket on_message方法中忽略了异常

时间:2015-11-15 19:15:57

标签: python tornado

我有以下课程:

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中的重复键被传播并显示在控制台中。

1 个答案:

答案 0 :(得分:3)

[此答案适用于Tornado 4.4及更早版本。截至Tornado 4.5 on_message可能是一个协程,原始问题中的代码可以正常工作]

与常规函数不同地调用协程(即必须使用yield调用它们)。因此,当您定义一个框架调用的方法时,您应该只在文档说出&#34之类的东西时使用协程;这个方法可能是一个协程"。 WebSocketHandler.on_message可能不是协程(截至Tornado 4.3)。

相反,您可以使用IOLoop.spawn_callbackon_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.lockstornado.queues模块中的方法来管理此并发。 (相比之下,在RequestHandler.data_received中,哪个可能是一个协程,在第二个数据被处理之前,你不会获得第二个数据块,并且未捕获的异常将中止连接)