Detect rate limits in methods that swallow 429 exceptions so the modal appears
This commit is contained in:
parent
c9549e8a9a
commit
de2cc6db7a
2 changed files with 29 additions and 0 deletions
|
|
@ -134,6 +134,31 @@ def _clear_rate_limit():
|
||||||
logger.info("Global rate limit ban cleared (including post-ban cooldown)")
|
logger.info("Global rate limit ban cleared (including post-ban cooldown)")
|
||||||
|
|
||||||
|
|
||||||
|
def _detect_and_set_rate_limit(exception, endpoint_name="unknown"):
|
||||||
|
"""Check if a Spotify exception is a 429 rate limit and activate global ban if so.
|
||||||
|
Returns True if rate limit was detected."""
|
||||||
|
error_str = str(exception)
|
||||||
|
if "429" in error_str or "rate limit" in error_str.lower():
|
||||||
|
# Try to extract Retry-After
|
||||||
|
retry_after = None
|
||||||
|
if hasattr(exception, 'headers') and exception.headers:
|
||||||
|
retry_after = exception.headers.get('Retry-After') or exception.headers.get('retry-after')
|
||||||
|
if retry_after:
|
||||||
|
try:
|
||||||
|
delay = int(retry_after)
|
||||||
|
except (ValueError, TypeError):
|
||||||
|
delay = 300 # Default 5 min if can't parse
|
||||||
|
else:
|
||||||
|
# Spotipy "Max Retries" means it already exhausted retries — assume long ban
|
||||||
|
if "max retries" in error_str.lower():
|
||||||
|
delay = 600 # 10 min default for exhausted retries
|
||||||
|
else:
|
||||||
|
delay = 300
|
||||||
|
_set_global_rate_limit(delay, endpoint_name)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def rate_limited(func):
|
def rate_limited(func):
|
||||||
"""Decorator to enforce rate limiting on Spotify API calls with retry and exponential backoff"""
|
"""Decorator to enforce rate limiting on Spotify API calls with retry and exponential backoff"""
|
||||||
@wraps(func)
|
@wraps(func)
|
||||||
|
|
@ -896,6 +921,7 @@ class SpotifyClient:
|
||||||
return album_data
|
return album_data
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
_detect_and_set_rate_limit(e, 'get_album')
|
||||||
logger.error(f"Error fetching album via Spotify: {e}")
|
logger.error(f"Error fetching album via Spotify: {e}")
|
||||||
# Fall through to iTunes fallback
|
# Fall through to iTunes fallback
|
||||||
|
|
||||||
|
|
@ -1007,6 +1033,7 @@ class SpotifyClient:
|
||||||
try:
|
try:
|
||||||
return self.sp.artist(artist_id)
|
return self.sp.artist(artist_id)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
_detect_and_set_rate_limit(e, 'get_artist')
|
||||||
logger.error(f"Error fetching artist via Spotify: {e}")
|
logger.error(f"Error fetching artist via Spotify: {e}")
|
||||||
# Fall through to iTunes fallback
|
# Fall through to iTunes fallback
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29235,6 +29235,8 @@ def enrich_similar_artists():
|
||||||
image_url=img_url, genres=genres, popularity=pop
|
image_url=img_url, genres=genres, popularity=pop
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
from core.spotify_client import _detect_and_set_rate_limit
|
||||||
|
_detect_and_set_rate_limit(e, 'enrich_similar_artists')
|
||||||
print(f"Error enriching Spotify batch: {e}")
|
print(f"Error enriching Spotify batch: {e}")
|
||||||
else:
|
else:
|
||||||
from core.itunes_client import iTunesClient
|
from core.itunes_client import iTunesClient
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue