fix(prometheus): a refused token stops the scraping, as Home Assistant bans an address after a few refusals (#6355)
CI / lint (push) Successful in 2s
CI / unit (push) Successful in 1m36s
CI / integration (push) Successful in 1m55s
CI / publish (push) Successful in 20s

Also names the Home Assistant connection by its address in the audit log and
timeline, where its id showed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-01 09:41:53 -05:00
co-authored by Claude Opus 5.5
parent a1dfa7b821
commit 66a5dd12fd
11 changed files with 94 additions and 11 deletions
+7 -2
View File
@@ -18,6 +18,11 @@ class ScrapeError(Exception):
"""Why a scrape got nothing, said to the person."""
class TokenRefused(ScrapeError):
"""The endpoint refused the token. Asking again won't change that, and
Home Assistant, for one, bans an address after a few refusals."""
async def scrape(url: str, token: str = "", verify_tls: bool = True,
transport: httpx.AsyncBaseTransport | None = None) -> dict[str, prometheus.Family]:
"""The endpoint's families. `transport` stands in for the network in tests."""
@@ -29,8 +34,8 @@ async def scrape(url: str, token: str = "", verify_tls: bool = True,
transport=transport, follow_redirects=False) as client:
async with client.stream("GET", url, headers=headers) as response:
if response.status_code in (401, 403):
raise ScrapeError(f"Answered {response.status_code}: the token was refused. "
"Check the token, or make a new one on the service.")
raise TokenRefused(f"Answered {response.status_code}: the token was refused. "
"Check the token, or make a new one on the service.")
if response.status_code != 200:
raise ScrapeError(f"Answered {response.status_code} {response.reason_phrase}, not metrics.")
body = bytearray()