Merge otto/ha-client-errors into main

This commit is contained in:
2026-06-10 23:29:30 +02:00
22 changed files with 331 additions and 93 deletions

View File

@@ -5,13 +5,25 @@ from dataclasses import dataclass
import requests
from app.ha.exceptions import HaAuthError, HaHttpError, HaTimeoutError, HaUnexpectedPayloadError
from app.ha.exceptions import (
HaAuthError,
HaHttpError,
HaTimeoutError,
HaUnexpectedPayloadError,
)
logger = logging.getLogger(__name__)
@dataclass(frozen=True)
class HaClientSettings:
url: str
token: str
timeout_seconds: int = 10
class HaClient:
def __init__(self, settings) -> None:
def __init__(self, settings: HaClientSettings) -> None:
self._settings = settings
self._session = requests.Session()
self._session.headers.update({
@@ -19,35 +31,44 @@ class HaClient:
"Content-Type": "application/json",
})
def list_entities(self):
url = f"{self._settings.url}/api/states"
def list_entities(self) -> list[dict[str, object]]:
try:
response = self._session.get(
url,
f"{self._settings.url}/api/states",
timeout=self._settings.timeout_seconds,
)
except requests.Timeout as exc:
raise HaTimeoutError("Zeitüberschreitung beim Zugriff auf Home Assistant.") from exc
except requests.RequestException as exc:
raise HaHttpError(
getattr(exc.response, "status_code", 502),
getattr(getattr(exc, "response", None), "status_code", 502),
"Netzwerkfehler beim Zugriff auf Home Assistant.",
) from exc
if response.status_code in (401, 403):
raise HaAuthError(response.status_code, "Authentifizierung bei Home Assistant fehlgeschlagen.")
raise HaAuthError(
response.status_code,
"Authentifizierung bei Home Assistant fehlgeschlagen.",
)
try:
response.raise_for_status()
except requests.HTTPError as exc:
raise HaHttpError(response.status_code, "Home Assistant meldet einen Fehler.") from exc
raise HaHttpError(
response.status_code,
"Home Assistant meldet einen Fehler.",
) from exc
try:
payload = response.json()
except ValueError as exc:
raise HaUnexpectedPayloadError("Antwort von Home Assistant ist kein gültiges JSON.") from exc
raise HaUnexpectedPayloadError(
"Antwort von Home Assistant ist kein gültiges JSON."
) from exc
if not isinstance(payload, list):
raise HaUnexpectedPayloadError("Antwort von Home Assistant hat unerwartetes Format.")
raise HaUnexpectedPayloadError(
"Antwort von Home Assistant hat unerwartetes Format."
)
return payload