title: Tornado: Task exception was never retrieved
body: <p>I'm getting an Exception in a Tornado WebSocket server but It gives no information in the trace to know which line of code or which step in my program it is originating from. I would like to find out so that I try-catch the origin of the exception.</p>
  
  <p>Error Trace: (No mention of any part of my files)</p>
  
  <pre><code>[E 200527 21:07:19 base_events:1608] Task exception was never retrieved
      future: &lt;Task finished coro=&lt;WebSocketProtocol13.write_message.&lt;locals&gt;.wrapper() done, defined at /usr/local/lib/python3.7/site-packages/tornado/websocket.py:1102&gt; exception=WebSocketClosedError()&gt;
      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
  </code></pre>
  
  <p>That Same Group of Traceback repeats over 16 times.</p>
  
  <p>Here is my code:</p>
  
  <pre><code>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) &lt; 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
  </code></pre>
  
  <p>I have tried catching the exceptions that may cause any error while sending messages to the websocket clients but this error still happens when clients connect to the server.</p>