From 3e45189830689e565a5a21c64298bfb1fe20c82a Mon Sep 17 00:00:00 2001 From: Walt Howd Date: Tue, 10 Nov 2026 04:35:29 +0000 Subject: [PATCH] Stop reconnecting the web socket once its session is closed When Home Assistant stops, it closes the shared HTTP session before the integration closes the client. The web socket monitor then tried to reconnect with the closed session and logged "Session is closed" as an error on every restart. Stop the monitor quietly instead. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01FxWHBTrHU6eTPotwMWgtJF --- src/rivian/ws_monitor.py | 5 +++++ tests/test_ws_monitor.py | 14 ++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/rivian/ws_monitor.py b/src/rivian/ws_monitor.py index ccf0bce..6e6e77e 100644 --- a/src/rivian/ws_monitor.py +++ b/src/rivian/ws_monitor.py @@ -339,6 +339,11 @@ async def _monitor(self) -> None: await asyncio.sleep(delay) if self._disconnect or self.connected: continue + # pylint: disable=protected-access + if (session := self._account._session) is None or session.closed: + # The HTTP session is gone (e.g. Home Assistant is stopping) + self._log_message("web socket monitor stopped, session closed") + break if not self._disconnect: try: await self.new_connection() diff --git a/tests/test_ws_monitor.py b/tests/test_ws_monitor.py index 3e9909b..7f5a4bd 100644 --- a/tests/test_ws_monitor.py +++ b/tests/test_ws_monitor.py @@ -580,3 +580,17 @@ async def connection_init(ws: ClientWebSocketResponse[bool]) -> None: assert unacked.rate_limited finally: WebSocketMonitor._shared_backoffs.clear() + + +async def test_monitor_stops_when_the_session_closes( + server: FakeServer, monitor: WebSocketMonitor, caplog: pytest.LogCaptureFixture +) -> None: + """Test a closed HTTP session stops the monitor quietly instead of reconnecting.""" + add_subscription(monitor) + await monitor.new_connection(start_monitor=True) + await wait_for(lambda: monitor.connection_ack.is_set()) + await monitor._account._session.close() + assert monitor.monitor + await wait_for(monitor.monitor.done) + assert server.connections == 1 + assert not [r for r in caplog.records if r.levelname == "ERROR"]