forecastsolar: wrap HA-ML WebSocket failures as ProviderError - #414
Merged
Conversation
ForecastSolarHomeAssistantML.get_raw_data_from_provider() let DNS, connection, and auth failures from the WebSocket client escape unwrapped. ForecastSolarBaseclass.refresh_data() only catches (ConnectionError, TimeoutError, ProviderError), so these exceptions bypassed the cache fallback entirely (same class of bug as #408 in FCSolar, but for the websockets-based HA-ML provider). Wrap OSError, WebSocketException, and RuntimeError from the fetch as ProviderError so cached forecast data remains usable until its TTL expires.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR improves reliability of the Home Assistant ML solar forecast provider by ensuring WebSocket DNS/connection/auth failures are surfaced as ProviderError, allowing ForecastSolarBaseclass.refresh_data() to fall back to cached raw data until TTL expiry.
Changes:
- Wrap
OSError,WebSocketException, andRuntimeErrorfrom the HA-ML WebSocket fetch path asProviderError. - Add regression tests covering DNS failure, WebSocket failure, auth failure, and cache fallback behavior on connection failure.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| tests/test_forecast_solar_homeassistant_ml.py | Adds regression tests asserting network/auth failures are wrapped and cache fallback remains effective. |
| src/batcontrol/forecastsolar/forecast_homeassistant_ml.py | Wraps WebSocket-related failures as ProviderError so baseclass error handling can use cached data. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Chain ProviderError from the original exception and log with a stack trace instead of discarding it via 'from None'. Unlike the fcsolar.py case this wraps, none of OSError/WebSocketException/RuntimeError here can carry the API token (it is sent as a post-connect JSON payload, never part of the URL or handshake), so there is no leak risk in keeping the original error for diagnostics. Addresses review feedback on PR #414.
Contributor
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.
Suppressed comments (1)
src/batcontrol/forecastsolar/forecast_homeassistant_ml.py:344
- Catching RuntimeError here also wraps the "event loop is already running" error from run_until_complete(). That turns a programming/usage error into a ProviderError, which can silently trigger cache fallback and make the underlying issue hard to diagnose. Guard against a running loop before calling run_until_complete (or avoid wrapping that specific RuntimeError).
try:
loop = asyncio.get_event_loop()
except RuntimeError:
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
try:
return loop.run_until_complete(self._fetch_entity_state_async())
except (OSError, WebSocketException, RuntimeError) as e:
logger.error(
'HomeAssistant WebSocket request failed for entity %s: %s',
self.entity_id, e, exc_info=True)
raise ProviderError(
f'HomeAssistant WebSocket request failed for entity {self.entity_id}: {e}'
) from e
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
ForecastSolarHomeAssistantML.get_raw_data_from_provider() let DNS,
connection, and auth failures from the WebSocket client escape
unwrapped. ForecastSolarBaseclass.refresh_data() only catches
(ConnectionError, TimeoutError, ProviderError), so these exceptions
bypassed the cache fallback entirely (same class of bug as #408 in
FCSolar, but for the websockets-based HA-ML provider).
Wrap OSError, WebSocketException, and RuntimeError from the fetch as
ProviderError so cached forecast data remains usable until its TTL
expires.