# Buggy code
async def _read_messages(self):
    """Process messages received on the WebSocket connection."""
    text_message_callback_executions: List[Future] = []
    while not self._stopped and self._websocket is not None:
        for future in text_message_callback_executions:
            if future.done():
                text_message_callback_executions.remove(future)

        try:
            # Wait for a message to be received, but timeout after a second so that
            # we can check if the socket has been closed, or if self._stopped is
            # True
            message = await self._websocket.receive(timeout=1)
        except asyncio.TimeoutError:
            if not self._websocket.closed:
                # We didn't receive a message within the timeout interval, but
                # aiohttp hasn't closed the socket, so ping responses must still be
                # returning
                continue
            self._logger.warning(
                "Websocket was closed (%s).", self._websocket.close_code
            )
            await self._dispatch_event(event="error", data=self._websocket.exception())
            self._websocket = None
            await self._dispatch_event(event="close")
            num_of_running_callbacks = len(text_message_callback_executions)
            if num_of_running_callbacks > 0:
                self._logger.info(
                    "WebSocket connection has been closed "
                    f"though {num_of_running_callbacks} callback executions were still in progress"
                )
            return

        if message.type == aiohttp.WSMsgType.TEXT:
            payload = message.json()
            event = payload.pop("type", "Unknown")
            # Asynchronously run callbacks to handle simultaneous incoming messages from Slack
            f = asyncio.ensure_future(self._dispatch_event(event, data=payload))
            text_message_callback_executions.append(f)
        elif message.type == aiohttp.WSMsgType.ERROR:
            self._logger.error("Received an error on the websocket: %r", message)
            await self._dispatch_event(event="error", data=message)
        elif message.type in (
            aiohttp.WSMsgType.CLOSE,
            aiohttp.WSMsgType.CLOSING,
            aiohttp.WSMsgType.CLOSED,
        ):
            self._logger.warning("Websocket was closed.")
            self._websocket = None
            await self._dispatch_event(event="close")
        else:
            self._logger.debug("Received unhandled message type: %r", message)


# Traceback (AttributeError)
2020-02-03 06:20:43,937 slack.rtm.client DEBUG [client.py:427]: Running 1 callbacks for event: 'error'
2020-02-03 06:20:43,937 slack.rtm.client ERROR [client.py:445]: When calling '#_event_error()' in the 'slackminion.bot' module the following error was raised: 'coroutine' object has no attribute '__dict__'
2020-02-03 06:20:43,938 asyncio ERROR [base_events.py:1604]: Task exception was never retrieved
future: <Task finished coro=<RTMClient._connect_and_read() done, defined at /root/.pex/install/slackclient-2.4.0-py2.py3-none-any.whl.18e6eaa75092884787122451d86752135e246402/slackclient-2.4.0-py2.py3-none-any.whl/slack/rtm/client.py:307> exception=AttributeError("'coroutine' object has no attribute '__dict__'") crea
ted at /root/.pex/install/slackclient-2.4.0-py2.py3-none-any.whl.18e6eaa75092884787122451d86752135e246402/slackclient-2.4.0-py2.py3-none-any.whl/slack/rtm/client.py:193>
source_traceback: Object created at (most recent call last):
File "/usr/lib/python3.7/runpy.py", line 193, in _run_module_as_main
"__main__", mod_spec)
File "/usr/lib/python3.7/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "__main__.py", line 32, in <module>
bootstrap_pex(__entry_point__)
File ".bootstrap/pex/pex_bootstrapper.py", line 155, in bootstrap_pex
pex.PEX(entry_point).execute()
File ".bootstrap/pex/pex.py", line 352, in execute
exit_code = self._wrap_coverage(self._wrap_profiling, self._execute)
File ".bootstrap/pex/pex.py", line 284, in _wrap_coverage
return runner(*args)
File ".bootstrap/pex/pex.py", line 315, in _wrap_profiling
return runner(*args)
File ".bootstrap/pex/pex.py", line 397, in _execute
return self.execute_entry(self._pex_info.entry_point)
File ".bootstrap/pex/pex.py", line 495, in execute_entry
return runner(entry_point)
File ".bootstrap/pex/pex.py", line 510, in execute_pkg_resources
return runner()
File "/root/.pex/code/7488d2d5788cc31e1aaa013c3e6ea8e9b6b2ad2a/pinterest/srebot/bot.py", line 61, in main
asyncio.run(srebot(), debug=True)
File "/usr/lib/python3.7/asyncio/runners.py", line 43, in run
return loop.run_until_complete(main)
File "/usr/lib/python3.7/asyncio/base_events.py", line 566, in run_until_complete
self.run_forever()
File "/usr/lib/python3.7/asyncio/base_events.py", line 534, in run_forever
self._run_once()
File "/usr/lib/python3.7/asyncio/base_events.py", line 1763, in _run_once
handle._run()
File "/usr/lib/python3.7/asyncio/events.py", line 88, in _run
self._context.run(self._callback, *self._args)
File "/root/.pex/code/7488d2d5788cc31e1aaa013c3e6ea8e9b6b2ad2a/pinterest/srebot/bot.py", line 50, in srebot
await bot.run()
File "/root/.pex/install/slackminion-0.10.28-py3-none-any.whl.55516cd422c7f852e172cf07bc46de807f9fcf27/slackminion-0.10.28-py3-none-any.whl/slackminion/bot.py", line 156, in run
self.rtm_client.start()
File "/root/.pex/install/slackclient-2.4.0-py2.py3-none-any.whl.18e6eaa75092884787122451d86752135e246402/slackclient-2.4.0-py2.py3-none-any.whl/slack/rtm/client.py", line 193, in start
future = asyncio.ensure_future(self._connect_and_read(), loop=self._event_loop)
Traceback (most recent call last):
File "/root/.pex/install/aiohttp-3.6.2-cp37-cp37m-manylinux1_x86_64.whl.ac8c04b4809f61b5e7d7d38dec8668ddf99c226d/aiohttp-3.6.2-cp37-cp37m-manylinux1_x86_64.whl/aiohttp/client_ws.py", line 227, in receive
msg = await self._reader.read()
File "/root/.pex/install/aiohttp-3.6.2-cp37-cp37m-manylinux1_x86_64.whl.ac8c04b4809f61b5e7d7d38dec8668ddf99c226d/aiohttp-3.6.2-cp37-cp37m-manylinux1_x86_64.whl/aiohttp/streams.py", line 631, in read
return await super().read()
File "/root/.pex/install/aiohttp-3.6.2-cp37-cp37m-manylinux1_x86_64.whl.ac8c04b4809f61b5e7d7d38dec8668ddf99c226d/aiohttp-3.6.2-cp37-cp37m-manylinux1_x86_64.whl/aiohttp/streams.py", line 591, in read
await self._waiter
concurrent.futures._base.CancelledError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/root/.pex/install/slackclient-2.4.0-py2.py3-none-any.whl.18e6eaa75092884787122451d86752135e246402/slackclient-2.4.0-py2.py3-none-any.whl/slack/rtm/client.py", line 371, in _read_messages
message = await self._websocket.receive(timeout=1)
File "/root/.pex/install/aiohttp-3.6.2-cp37-cp37m-manylinux1_x86_64.whl.ac8c04b4809f61b5e7d7d38dec8668ddf99c226d/aiohttp-3.6.2-cp37-cp37m-manylinux1_x86_64.whl/aiohttp/client_ws.py", line 227, in receive
msg = await self._reader.read()
File "/root/.pex/install/async_timeout-3.0.1-py3-none-any.whl.71cea41869a7c1638badbd9362a317bfeccf5203/async_timeout-3.0.1-py3-none-any.whl/async_timeout/__init__.py", line 45, in __exit__
self._do_exit(exc_type)
File "/root/.pex/install/async_timeout-3.0.1-py3-none-any.whl.71cea41869a7c1638badbd9362a317bfeccf5203/async_timeout-3.0.1-py3-none-any.whl/async_timeout/__init__.py", line 92, in _do_exit
raise asyncio.TimeoutError
concurrent.futures._base.TimeoutError

# Fixed code
async def _read_messages(self):
    """Process messages received on the WebSocket connection."""
    text_message_callback_executions: List[Future] = []
    while not self._stopped and self._websocket is not None:
        for future in text_message_callback_executions:
            if future.done():
                text_message_callback_executions.remove(future)

        try:
            # Wait for a message to be received, but timeout after a second so that
            # we can check if the socket has been closed, or if self._stopped is
            # True
            message = await self._websocket.receive(timeout=1)
        except asyncio.TimeoutError:
            if not self._websocket.closed:
                # We didn't receive a message within the timeout interval, but
                # aiohttp hasn't closed the socket, so ping responses must still be
                # returning
                continue
            self._logger.warning(
                "Websocket was closed (%s).", self._websocket.close_code
            )
            await self._dispatch_event(event="error", data=self._websocket.exception())
            self._websocket = None
            await self._dispatch_event(event="close")
            num_of_running_callbacks = len(text_message_callback_executions)
            if num_of_running_callbacks > 0:
                self._logger.info(
                    "WebSocket connection has been closed "
                    f"though {num_of_running_callbacks} callback executions were still in progress"
                )
            return

        if message.type == aiohttp.WSMsgType.TEXT:
            payload = message.json()
            event = payload.pop("type", "Unknown")

            async def run_dispatch_event():
                try:
                    await self._dispatch_event(event, data=payload)
                except Exception as err:
                    data = message.data if message else message
                    self._logger.info(
                        f"Caught a raised exception ({err}) while dispatching a TEXT message ({data})"
                    )
                    # Raised exceptions here happen in users' code and were just unhandled.
                    # As they're not intended for closing current WebSocket connection,
                    # this exception should not be propagated to higher level (#_connect_and_read()).
                    return

            # Asynchronously run callbacks to handle simultaneous incoming messages from Slack
            f = asyncio.ensure_future(run_dispatch_event())
            text_message_callback_executions.append(f)
        elif message.type == aiohttp.WSMsgType.ERROR:
            self._logger.error("Received an error on the websocket: %r", message)
            await self._dispatch_event(event="error", data=message)
        elif message.type in (
            aiohttp.WSMsgType.CLOSE,
            aiohttp.WSMsgType.CLOSING,
            aiohttp.WSMsgType.CLOSED,
        ):
            self._logger.warning("Websocket was closed.")
            self._websocket = None
            await self._dispatch_event(event="close")
        else:
            self._logger.debug("Received unhandled message type: %r", message)