diff --git a/redbot/core/bot.py b/redbot/core/bot.py index 786bf8b9f..6b3956247 100644 --- a/redbot/core/bot.py +++ b/redbot/core/bot.py @@ -1370,7 +1370,8 @@ class RedBase( await super().logout() await drivers.get_driver_class().teardown() try: - await self.rpc.close() + if self.rpc_enabled: + await self.rpc.close() except AttributeError: pass diff --git a/redbot/core/rpc.py b/redbot/core/rpc.py index da9b30e1c..6308f9cb0 100644 --- a/redbot/core/rpc.py +++ b/redbot/core/rpc.py @@ -1,4 +1,5 @@ import asyncio +import sys from typing import Optional from aiohttp import web @@ -68,23 +69,38 @@ class RPC: self._runner = web.AppRunner(self.app) self._site: Optional[web.TCPSite] = None + self._started = False async def initialize(self, port: int): """ Finalizes the initialization of the RPC server and allows it to begin accepting queries. """ - await self._runner.setup() - self._site = web.TCPSite(self._runner, host="127.0.0.1", port=port, shutdown_timeout=0) - await self._site.start() - log.debug("Created RPC server listener on port %s", port) + try: + # This ensures self._started can't be assigned + # except with both other functions + # and isn't subject to a really really stupid but complex + # issue on windows with catching specific + # exceptions related to shutdown conditions in asyncio applications. + self._started, _discard, self._site = ( + True, + await self._runner.setup(), + web.TCPSite(self._runner, host="127.0.0.1", port=port, shutdown_timeout=0), + ) + except Exception as exc: + log.exception("RPC setup failure", exc_info=exc) + sys.exit(1) + else: + await self._site.start() + log.debug("Created RPC server listener on port %s", port) async def close(self): """ Closes the RPC server. """ - await self.app.shutdown() - await self._runner.cleanup() + if self._started: + await self.app.shutdown() + await self._runner.cleanup() def add_method(self, method, prefix: str = None): if prefix is None: