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:
EloquentBrush0x 2026-05-18 22:06:53 +03:00 committed by Teknium
parent 242962e1f5
commit 9bd5003d4f
2 changed files with 144 additions and 3 deletions

View file

@ -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: