Skip to content

Raise AuthenticationException on runtime auth failures - #43

Open
nameetpai wants to merge 2 commits into
jaraco:mainfrom
nameetpai:fix/runtime-auth-reauth
Open

Raise AuthenticationException on runtime auth failures#43
nameetpai wants to merge 2 commits into
jaraco:mainfrom
nameetpai:fix/runtime-auth-reauth

Conversation

@nameetpai

Copy link
Copy Markdown

Summary

Today Client._send_request collapses every non-success outcome into a generic
jaraco.abode.Exception(ERROR.REQUEST). Callers therefore can't tell a transient
network/server error apart from an authentication failure (expired token whose
re-login no longer works, changed password, revoked session, etc.).

This change makes the library surface authentication failures as the dedicated
AuthenticationException so downstream consumers can react appropriately — most
notably Home Assistant, which wants to start a reauthentication flow rather than
silently retry forever. This was requested during review of
home-assistant/core#166429, where the maintainer asked that the auth-detection
logic live in this library and raise a dedicated authentication error.

What changed

  • Client._send_request now raises AuthenticationException when the response
    indicates an auth failure, via the new AuthenticationException.detect() /
    AuthenticationException.from_response() helpers.
  • Detection covers:
    • HTTP status codes 400, 401, 403.
    • Auth-error payloads that Abode occasionally returns with an HTTP 200
      (application error codes 11002 / 13027, or messages such as
      "unauthorized" / "invalid credentials" / "password … match"). The content
      type is checked before the body is parsed, and parsing is guarded.
  • AuthenticationException subclasses jaraco.abode.Exception, so it is still
    trapped by send_request's single retry (cleanup=self.login). Transient
    token expiry keeps recovering exactly as before; only a persistent auth
    failure now propagates as AuthenticationException.
  • best_message is made more robust (case-insensitive content-type match,
    guarded JSON parsing, no KeyError when message is absent).

Backwards compatibility

AuthenticationException is a subclass of jaraco.abode.Exception, so existing
except jaraco.abode.Exception: handlers continue to catch these failures. No
public signatures change.

Tests

tests/test_auth_handling.py adds:

  • Unit tests for detect() / from_response() across status codes, auth-like
    200 payloads, non-dict/invalid JSON bodies, and plain-text bodies.
  • Integration tests (via the existing m/responses fixtures) asserting that a
    persistent 403, and an auth-error payload returned with 200, both raise
    AuthenticationException, while a single 403 followed by success still
    recovers through re-login.

A newsfragment is included (newsfragments/+runtime-auth.feature.rst).

send_request now raises AuthenticationException when a request fails because
authentication is no longer valid, including auth-error payloads returned with
an HTTP 200. Adds AuthenticationException.detect/from_response helpers so
downstream consumers (e.g. Home Assistant) can trigger reauthentication.
bafulton added a commit to bafulton/homelab that referenced this pull request Jun 3, 2026
…cket reconnect

Wraps _on_socket_started in a try-except so failed session cookie
refreshes are logged at DEBUG instead of ERROR. Repeated 403s from
this callback trigger Cloudflare rate limiting upstream, eventually
causing full integration failure (HA issues #152205, #172809).

Remove once jaraco/jaraco.abode#43 is released and picked up by HA.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant