From ccd2dace1322ded5fc4d14dd91002624fc2330d2 Mon Sep 17 00:00:00 2001 From: Zo Bot Date: Fri, 19 Jun 2026 01:40:33 +0000 Subject: [PATCH] narrow bare except in twisted errback to Exception MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The errback handler for Deferred-to-Future conversion wrapped failure.raiseException() (the standard way to re-raise a twisted Failure as its underlying exception) plus a defensive 'raise Exception("errback called without error")' (in case the Failure wrapped no exception at all). The bare 'except:' caught every BaseException including KeyboardInterrupt and SystemExit. The handler's intent is to capture the exception info so it can be stashed on the Future (so the awaiter sees the right error), so narrowing to 'except Exception' is the right shape: a real KeyboardInterrupt raised inside the twisted reactor (e.g. the caller pressed Ctrl-C in a different thread, or twisted itself propagated Ctrl-C from a signal handler) should now propagate out to the tornado event loop instead of being silently converted to a Future exception that the awaiter would observe as a generic 'errback called without error' message. A real SystemExit raised inside twisted (e.g. via a signal handler that the user wired themselves, or a twisted plugin that called sys.exit on a shutdown) similarly propagates to the IOLoop's atexit hooks instead of being hidden inside a Future result. MemoryError and RecursionError are not caught by 'except Exception' either, which is the right behavior — a Future is the wrong place to attempt to record a process-level resource exhaustion. --- tornado/platform/twisted.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tornado/platform/twisted.py b/tornado/platform/twisted.py index 04c9e4e56..d3d7e57c6 100644 --- a/tornado/platform/twisted.py +++ b/tornado/platform/twisted.py @@ -56,7 +56,7 @@ def errback(failure: failure.Failure) -> None: failure.raiseException() # Should never happen, but just in case raise Exception("errback called without error") - except: + except Exception: future_set_exc_info(f, sys.exc_info()) d.addCallbacks(f.set_result, errback)