From e00a41183724f62661423720aa271ef74fee6ea0 Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Mon, 3 Nov 2025 11:18:56 -0600 Subject: [PATCH] Move exception handling up the stack (avoid `exit(1)` in our composable functions) (#19116) Move exception handling up the stack (avoid `exit(1)` in our composable functions) Relevant to Synapse Pro for small hosts as we don't want to exit the entire Python process and affect all homeserver tenants. ### Background As part of Element's plan to support a light form of vhosting (virtual host) (multiple instances of Synapse in the same Python process) (c.f Synapse Pro for small hosts), we're currently diving into the details and implications of running multiple instances of Synapse in the same Python process. "Clean tenant provisioning" tracked internally by https://github.com/element-hq/synapse-small-hosts/issues/48 --- changelog.d/19116.misc | 1 + synapse/app/generic_worker.py | 16 ++++++++-------- synapse/app/homeserver.py | 10 +++++----- 3 files changed, 14 insertions(+), 13 deletions(-) create mode 100644 changelog.d/19116.misc diff --git a/changelog.d/19116.misc b/changelog.d/19116.misc new file mode 100644 index 000000000..2291d0781 --- /dev/null +++ b/changelog.d/19116.misc @@ -0,0 +1 @@ +Move exception handling up the stack (avoid `exit(1)` in our composable functions). diff --git a/synapse/app/generic_worker.py b/synapse/app/generic_worker.py index 8f512c157..1a7bedaac 100644 --- a/synapse/app/generic_worker.py +++ b/synapse/app/generic_worker.py @@ -364,14 +364,11 @@ def start(config: HomeServerConfig) -> None: # Start the tracer init_tracer(hs) # noqa - try: - hs.setup() + hs.setup() - # Ensure the replication streamer is always started in case we write to any - # streams. Will no-op if no streams can be written to by this worker. - hs.get_replication_streamer() - except Exception as e: - handle_startup_exception(e) + # Ensure the replication streamer is always started in case we write to any + # streams. Will no-op if no streams can be written to by this worker. + hs.get_replication_streamer() async def start() -> None: await _base.start(hs) @@ -388,7 +385,10 @@ def start(config: HomeServerConfig) -> None: def main() -> None: homeserver_config = load_config(sys.argv[1:]) with LoggingContext(name="main", server_name=homeserver_config.server.server_name): - start(homeserver_config) + try: + start(homeserver_config) + except Exception as e: + handle_startup_exception(e) if __name__ == "__main__": diff --git a/synapse/app/homeserver.py b/synapse/app/homeserver.py index 023a0d877..9fd65b271 100644 --- a/synapse/app/homeserver.py +++ b/synapse/app/homeserver.py @@ -414,10 +414,7 @@ def setup( # Start the tracer init_tracer(hs) # noqa - try: - hs.setup() - except Exception as e: - handle_startup_exception(e) + hs.setup() async def _start_when_reactor_running() -> None: # TODO: Feels like this should be moved somewhere else. @@ -464,7 +461,10 @@ def main() -> None: # check base requirements check_requirements() hs = create_homeserver(homeserver_config) - setup(hs) + try: + setup(hs) + except Exception as e: + handle_startup_exception(e) # redirect stdio to the logs, if configured. if not hs.config.logging.no_redirect_stdio: