Skip to content

fix: retry once with new credentials after a rejected token - #559

Open
ScribleSean wants to merge 1 commit into
webdjoe:devfrom
ScribleSean:fix/reauth-retry-loop
Open

ScribleSean wants to merge 1 commit into
webdjoe:devfrom
ScribleSean:fix/reauth-retry-loop

Conversation

@ScribleSean

Copy link
Copy Markdown

Fixes #558.

When the API rejects a token, the library logs in again and retries. The retry resent the original request body, old token included, and dropped the headers, so it was rejected again and triggered another login. That repeated until Python's recursion limit or a VeSync rate limit.

What changed

All in src/pyvesync/vesync.py:

  • The retry now carries the new credentials. _with_current_credentials() returns a copy of the body or headers with token / tk and accountID / accountId replaced by the manager's current values.
  • The retry passes the original headers through.
  • A call retries at most once. async_call_api takes a keyword-only _reauth_retry flag, and a rejected retry raises VeSyncTokenError instead of logging in again.

The existing _api_attempts counter and MAX_API_REAUTH_RETRIES are left as they are.

Tests

src/tests/test_reauth_retry.py drives async_call_api through a fake session:

  • a rejected token causes one re-login and one retry, with the new token and account ID in the body and the original headers
  • credentials carried in headers (tk, accountId) are refreshed
  • a token rejected again after the retry raises VeSyncTokenError, with one re-login in total

The first test fails with RecursionError without the fix.

pytest src/tests: 383 passed, 3 skipped. ruff check and ruff format --check are clean. mypy reports the same two errors in vesyncthermostat.py as dev.

Notes

  • Only top-level keys are refreshed. I did not find a request that nests the token deeper, but I have only been able to check against the code, not every device.
  • The caller's dict is not modified; the retry uses a copy.

A rejected token triggered a re-login followed by a retry that resent the
original request body, including the old token, and dropped the headers.
The server rejected it again, which triggered another re-login, without
limit.

Refresh the token and account ID in the body and headers before the retry,
pass the headers through, and allow a single retry per call.

Fixes webdjoe#558.

This branch has not been deployed

No deployments
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.

Rejected token causes unbounded re-login loop: retry reuses the old token

1 participant