Retry registry queries and surface failures as clean errors

This commit is contained in:
J. Nick Koston
2026-08-20 07:34:41 -05:00
parent dad9a1175b
commit a005008cfb
2 changed files with 50 additions and 3 deletions
+14 -3
View File
@@ -138,9 +138,20 @@ def _registry_download(package: str, version: str) -> tuple[str, str, int | None
import requests
url = _REGISTRY_URL.format(package=package)
resp = requests.get(url, timeout=30)
resp.raise_for_status()
data = resp.json()
last_err: Exception | None = None
for _ in range(3):
try:
resp = requests.get(url, timeout=30)
resp.raise_for_status()
data = resp.json()
break
except requests.RequestException as err:
last_err = err
else:
# A clean, retried error like the other download paths in the tree
raise EsphomeError(
f"Could not query the package registry for {package}: {last_err}"
) from last_err
system = _pio_system()
for ver in data.get("versions", []):
if ver.get("name") != version:
@@ -81,6 +81,42 @@ def _registry_response(files: list[dict]) -> MagicMock:
return resp
def test_registry_download_network_error_is_clean_and_retried() -> None:
"""Registry failures raise EsphomeError after retries, not a traceback."""
import requests
with (
patch("requests.get", side_effect=requests.ConnectionError("boom")) as mock_get,
pytest.raises(EsphomeError, match="Could not query the package registry"),
):
framework._registry_download("pkg", "1.0.0")
assert mock_get.call_count == 3
def test_registry_download_retries_transient_error() -> None:
import requests
resp = _registry_response(
[
{
"system": ["linux_x86_64"],
"download_url": "http://x/linux",
"checksum": {"sha256": "abc123"},
"size": 42,
}
]
)
with (
patch("requests.get", side_effect=[requests.ConnectionError("boom"), resp]),
patch.object(framework, "_pio_system", return_value="linux_x86_64"),
):
assert framework._registry_download("pkg", "1.0.0") == (
"http://x/linux",
"abc123",
42,
)
def test_registry_download_matches_system() -> None:
resp = _registry_response(
[