【问题标题】:Tornado: Task exception was never retrievedTornado:从未检索到任务异常
【发布时间】:2020-05-27 20:45:18
【问题描述】:

我在 Tornado WebSocket 服务器中遇到异常,但它在跟踪中没有提供任何信息来知道它来自哪一行代码或我的程序中的哪个步骤。我想知道,以便我尝试捕获异常的来源。

错误跟踪:(没有提及我的文件的任何部分)

[E 200527 21:07:19 base_events:1608] Task exception was never retrieved
    future: <Task finished coro=<WebSocketProtocol13.write_message.<locals>.wrapper() done, defined at /usr/local/lib/python3.7/site-packages/tornado/websocket.py:1102> exception=WebSocketClosedError()>
    Traceback (most recent call last):
    File "/usr/local/lib/python3.7/site-packages/tornado/websocket.py", line 1104, in wrapper
        await fut
    tornado.iostream.StreamClosedError: Stream is closed

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last):
    File "/usr/local/lib/python3.7/site-packages/tornado/websocket.py", line 1106, in wrapper
        raise WebSocketClosedError()
    tornado.websocket.WebSocketClosedError

[E 200527 21:07:19 base_events:1608] Task exception was never retrieved

同一组 Traceback 重复超过 16 次。

这是我的代码:

import tornado.iostream
import tornado.web
import tornado.gen
import tornado.websocket
import asyncio

class SocketHandler(tornado.websocket.WebSocketHandler):
    waiters = set()
    def initialize(self):
        self.client_name = "newly_connected"

    def get_compression_options(self):
        # Non-None enables compression with default options.
        return {}

    def open(self):
        print('connection opened')
        # SocketHandler.waiters.add(self)

    def on_close(self):
        print("CLOSED!", self.client_name)
        try:
            SocketHandler.waiters.remove(self)
        except KeyError:
            print('tried removing new client')

    def check_origin(self, origin):
        # Override the origin check if needed
        return True

    @classmethod
    async def send_updates(cls, message):
        if len(cls.waiters) < 2:
            while True:
                chat = {}
                # Prevent RuntimeError: Set changed size during iteration
                waiters_copy = cls.waiters.copy()
                for waiter in waiters_copy:
                    try:
                        await waiter.write_message(chat)
                    except tornado.websocket.WebSocketClosedError:
                        pass
                    except tornado.iostream.StreamClosedError:
                        pass
                    except Exception as e:
                        print('Exception e:', waiter.client_name)
                        pass

                # sleep a bit
                await asyncio.sleep(0.05)
        else:
            print('broadcast loop already running')

    async def on_message(self, message):
        print("RECEIVED :", message)
        self.client_name = message
        self.first_serve_cache_on_connnect()
        SocketHandler.waiters.add(self)
        await SocketHandler.send_updates(message)

    def first_serve_cache_on_connnect(self):
        print('serving cache on connect')
        temp_calc_results = self.namespace.results
        try:
            self.write_message(temp_calc_results)
        except Exception as e:
            pass

我已经尝试在向 websocket 客户端发送消息时捕获可能导致任何错误的异常,但是当客户端连接到服务器时仍然会发生此错误。

【问题讨论】:

    标签: python websocket tornado python-asyncio


    【解决方案1】:

    消息“从未检索到任务异常”不是关于缺少try/except 块,而是关于缺少await。在first_serve_cache_on_connect 中,您在没有await 的情况下调用write_message,所以first_serve_cache_on_connect 在引发异常时不再运行,它除了日志无处可去。

    这基本上是无害的,但是如果你想清理你的日志,你需要使first_serve_cache_on_connect成为async def协程,在on_message中用await调用它,用@987654332调用write_message @。

    【讨论】:

    • 那么为什么first_serve_cache_on_connect 中的try-except 块不会捕获该异常?
    • 在调用write_message 时不会引发异常,在调用awaited 时会引发异常。如果没有 await,try/except 块在异常发生时已经消失。
    猜你喜欢
    • 1970-01-01
    • 2022-07-07
    • 2020-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-29
    • 2016-11-25
    • 1970-01-01
    相关资源
    最近更新 更多