From 489a127056eef88a68a77a17bbab0e0faa5095d3 Mon Sep 17 00:00:00 2001 From: Brian Krabach Date: Wed, 1 Apr 2026 14:13:45 -0700 Subject: [PATCH] refactor: defensive getattr guard and clarified cleanup comment in lifespan - Use getattr(app.state, 'federation_client', None) in shutdown to guard against the theoretical case where AsyncClient constructor raised before setting app.state.federation_client - Rename 'Shutdown:' comment to 'Cleanup:' in the finally block to better describe that the block covers both the poll-task cancellation and the overall cleanup guarantee --- muxplex/main.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/muxplex/main.py b/muxplex/main.py index 7d6cc3e..c65932f 100644 --- a/muxplex/main.py +++ b/muxplex/main.py @@ -183,11 +183,13 @@ async def lifespan(app: FastAPI): yield try: - await app.state.federation_client.aclose() + client = getattr(app.state, "federation_client", None) + if client is not None: + await client.aclose() except Exception: _log.exception("federation_client aclose error") finally: - # Shutdown: cancel the poll loop task and wait for it to finish. + # Cleanup: cancel the poll loop task and wait for it to finish. if _poll_task is not None: _poll_task.cancel() try: