From b041d6252ca3a17d01864a3b21a94c02ff667577 Mon Sep 17 00:00:00 2001 From: Zo Bot Date: Fri, 19 Jun 2026 01:37:05 +0000 Subject: [PATCH] narrow bare except around super().initialize() in AsyncioSelectorLoop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The bare 'except Exception:' wrapped super().initialize(**kwargs) in the asyncio-backed IOLoop initialize(), with a fallback that closes the newly-created asyncio event loop if the super initialize failed (taking ownership of the loop was not successful). The narrow set covers the actual failures of IOLoop initialize: OSError (file descriptor limit reached when opening the epoll/kqueue/select fd, can't bind, can't open /dev/null for stderr redirection), RuntimeError (asyncio loop already running, or a conflicting call to asyncio.set_event_loop), ValueError (an explicit invalid arg check inside the super) and TypeError (an unexpected kwarg passed through **kwargs from a downstream caller that the asyncio loop's initializer doesn't accept). KeyboardInterrupt and SystemExit are BaseException and were being swallowed by the bare 'except Exception' — narrowing lets a Ctrl-C during IOLoop initialize propagate immediately to whatever the caller of AsyncioSelectorLoop.initialize was, instead of being caught, running the loop.close() fallback, and re-raised as a new chained exception. --- tornado/platform/asyncio.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tornado/platform/asyncio.py b/tornado/platform/asyncio.py index b7b63d199..bfe6d22b8 100644 --- a/tornado/platform/asyncio.py +++ b/tornado/platform/asyncio.py @@ -327,7 +327,7 @@ def initialize(self, **kwargs: Any) -> None: # type: ignore kwargs["asyncio_loop"] = loop = asyncio.new_event_loop() try: super().initialize(**kwargs) - except Exception: + except (OSError, RuntimeError, ValueError, TypeError): # If initialize() does not succeed (taking ownership of the loop), # we have to close it. if loop is not None: