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"]