fix(spotify): quarantine dead tokens on terminal refresh failure
resolve_spotify_runtime_credentials() called _refresh_spotify_oauth_state() without a try/except, so a terminal failure (HTTP 400/401, invalid_grant, refresh_token_reused) raised AuthError but left the dead refresh_token in auth.json. Every subsequent session re-read and retried the same token over the network, failing identically each time. Fix: wrap the refresh call and, when exc.relogin_required is True and a refresh_token is present, clear the dead OAuth fields (access_token, refresh_token, expires_at, expires_in, obtained_at) and write a last_auth_error quarantine marker to auth.json before re-raising. The next call sees no access_token and fails fast with spotify_access_token_missing — no network retry — and the user is prompted to re-authenticate. Mirrors the quarantine pattern already in place for Nous, xAI-OAuth, Codex-OAuth (#28116, #28118), and MiniMax-OAuth (#28119).
This commit is contained in:
parent
242962e1f5
commit
9bd5003d4f
2 changed files with 144 additions and 3 deletions
|
|
@ -2899,9 +2899,31 @@ def resolve_spotify_runtime_credentials(
|
|||
if not should_refresh and refresh_if_expiring:
|
||||
should_refresh = _is_expiring(state.get("expires_at"), refresh_skew_seconds)
|
||||
if should_refresh:
|
||||
state = _refresh_spotify_oauth_state(state)
|
||||
_store_provider_state(auth_store, "spotify", state, set_active=False)
|
||||
_save_auth_store(auth_store)
|
||||
try:
|
||||
state = _refresh_spotify_oauth_state(state)
|
||||
_store_provider_state(auth_store, "spotify", state, set_active=False)
|
||||
_save_auth_store(auth_store)
|
||||
except AuthError as exc:
|
||||
if exc.relogin_required and state.get("refresh_token"):
|
||||
# Terminal refresh failure — clear dead tokens from auth.json
|
||||
# so subsequent calls fail fast without a network retry.
|
||||
# Mirrors the Nous / xAI-OAuth / Codex-OAuth / MiniMax pattern.
|
||||
for _k in ("access_token", "refresh_token", "expires_at", "expires_in", "obtained_at"):
|
||||
state.pop(_k, None)
|
||||
state["last_auth_error"] = {
|
||||
"provider": "spotify",
|
||||
"code": exc.code or "refresh_failed",
|
||||
"message": str(exc),
|
||||
"reason": "runtime_refresh_failure",
|
||||
"relogin_required": True,
|
||||
"at": datetime.now(timezone.utc).isoformat(),
|
||||
}
|
||||
try:
|
||||
_store_provider_state(auth_store, "spotify", state, set_active=False)
|
||||
_save_auth_store(auth_store)
|
||||
except Exception as _save_exc:
|
||||
logger.debug("Spotify OAuth: failed to persist quarantined state: %s", _save_exc)
|
||||
raise
|
||||
|
||||
access_token = str(state.get("access_token", "") or "").strip()
|
||||
if not access_token:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue