Surface silent exceptions in metadata clients — 37 sites

- spotify_client.py: 15 sites (mostly `publish_spotify_status` + cache
  parse fallbacks)
- deezer_client.py: 10 sites (cache get/store + dataclass parsing)
- itunes_client.py: 4 sites (cache parsing + lookup fallback)
- discogs_client.py: 3 sites (cache parsing + token-from-config)
- tidal_client.py: 2 sites (used `_e` to avoid shadowing `e` from a
  sibling `except` clause in the same function — defensive)
- deezer_download_client.py: 3 sites

All converted to `logger.debug("...: %s", e)` with lazy formatter.
No control-flow changes.

Refs #369
pull/516/head
Broque Thomas 1 week ago
parent e4e6b6bd5a
commit cc7a3f76ac

@ -307,8 +307,8 @@ class DeezerClient:
for raw in cached_results:
try:
tracks.append(Track.from_deezer_track(raw))
except Exception:
pass
except Exception as e:
logger.debug("Track.from_deezer_track cache parse: %s", e)
if tracks:
return tracks
@ -341,8 +341,8 @@ class DeezerClient:
for raw in cached_results:
try:
artists.append(Artist.from_deezer_artist(raw))
except Exception:
pass
except Exception as e:
logger.debug("Artist.from_deezer_artist cache parse: %s", e)
if artists:
return artists
@ -375,8 +375,8 @@ class DeezerClient:
for raw in cached_results:
try:
albums.append(Album.from_deezer_album(raw))
except Exception:
pass
except Exception as e:
logger.debug("Album.from_deezer_album cache parse: %s", e)
if albums:
return albums
@ -842,8 +842,8 @@ class DeezerClient:
try:
cache = get_metadata_cache()
cache.store_entity('deezer', 'artist', str(result.get('id', '')), result)
except Exception:
pass
except Exception as e:
logger.debug("cache store_entity artist search: %s", e)
logger.debug(f"Found artist for query: {artist_name}")
return result
@ -887,8 +887,8 @@ class DeezerClient:
try:
cache = get_metadata_cache()
cache.store_entity('deezer', 'album', str(result.get('id', '')), result)
except Exception:
pass
except Exception as e:
logger.debug("cache store_entity album search: %s", e)
logger.debug(f"Found album for query: {artist_name} - {album_title}")
return result
@ -932,8 +932,8 @@ class DeezerClient:
try:
cache = get_metadata_cache()
cache.store_entity('deezer', 'track', str(result.get('id', '')), result)
except Exception:
pass
except Exception as e:
logger.debug("cache store_entity track search: %s", e)
logger.debug(f"Found track for query: {artist_name} - {track_title}")
return result
@ -965,8 +965,8 @@ class DeezerClient:
# Cache hit with full details (has label = was a get_album response, not just search)
logger.debug(f"Cache hit for album {album_id}")
return cached
except Exception:
pass
except Exception as e:
logger.debug("cache get_entity album: %s", e)
try:
response = self.session.get(
@ -984,8 +984,8 @@ class DeezerClient:
try:
cache = get_metadata_cache()
cache.store_entity('deezer', 'album', str(album_id), data)
except Exception:
pass
except Exception as e:
logger.debug("cache store_entity album full: %s", e)
logger.debug(f"Got full album details for ID: {album_id}")
return data
@ -1013,8 +1013,8 @@ class DeezerClient:
if cached and cached.get('bpm'):
logger.debug(f"Cache hit for track {track_id}")
return cached
except Exception:
pass
except Exception as e:
logger.debug("cache get_entity track: %s", e)
try:
response = self.session.get(
@ -1032,8 +1032,8 @@ class DeezerClient:
try:
cache = get_metadata_cache()
cache.store_entity('deezer', 'track', str(track_id), data)
except Exception:
pass
except Exception as e:
logger.debug("cache store_entity track full: %s", e)
logger.debug(f"Got full track details for ID: {track_id}")
return data

@ -430,8 +430,8 @@ class DeezerDownloadClient(DownloadSourcePlugin):
if cached and cached.get('release_date'):
album_release_dates[aid] = cached['release_date']
continue
except Exception:
pass
except Exception as e:
logger.debug("cache get_entity album release_date: %s", e)
# Cache miss — fetch from API
try:
time.sleep(0.3) # Respect rate limits
@ -443,10 +443,10 @@ class DeezerDownloadClient(DownloadSourcePlugin):
if cache:
try:
cache.store_entity('deezer', 'album', aid, a_data)
except Exception:
pass
except Exception:
pass
except Exception as e:
logger.debug("cache store_entity album release_date: %s", e)
except Exception as e:
logger.debug("fetch deezer album release_date %s: %s", aid, e)
tracks = []
for i, t in enumerate(raw_tracks, start=1):

@ -320,8 +320,8 @@ class DiscogsClient:
try:
from config.settings import config_manager
self.token = config_manager.get('discogs.token', '')
except Exception:
pass
except Exception as e:
logger.debug("load discogs.token from config: %s", e)
if self.token:
self.session.headers['Authorization'] = f'Discogs token={self.token}'
@ -499,8 +499,8 @@ class DiscogsClient:
for raw in cached_results:
try:
artists.append(Artist.from_discogs_artist(raw))
except Exception:
pass
except Exception as e:
logger.debug("Artist.from_discogs_artist cache parse: %s", e)
if artists:
return artists
@ -536,8 +536,8 @@ class DiscogsClient:
for raw in cached_results:
try:
albums.append(Album.from_discogs_release(raw))
except Exception:
pass
except Exception as e:
logger.debug("Album.from_discogs_release cache parse: %s", e)
if albums:
return albums

@ -380,8 +380,8 @@ class iTunesClient:
for raw in cached_results:
try:
tracks.append(Track.from_itunes_track(raw))
except Exception:
pass
except Exception as e:
logger.debug("Track.from_itunes_track cache parse: %s", e)
if tracks:
return tracks
@ -569,8 +569,8 @@ class iTunesClient:
for raw in cached_results:
try:
albums.append(Album.from_itunes_album(raw))
except Exception:
pass
except Exception as e:
logger.debug("Album.from_itunes_album cache parse: %s", e)
if albums:
return albums
@ -893,8 +893,8 @@ class iTunesClient:
for item in results:
if item.get('wrapperType') == 'artist' and item.get('artistName'):
return item['artistName']
except Exception:
pass
except Exception as e:
logger.debug("itunes lookup artistId %s: %s", artist_id, e)
return None
def search_artists(self, query: str, limit: int = 20) -> List[Artist]:
@ -911,8 +911,8 @@ class iTunesClient:
for raw in cached_results:
try:
artists.append(Artist.from_itunes_artist(raw))
except Exception:
pass
except Exception as e:
logger.debug("Artist.from_itunes_artist cache parse: %s", e)
if artists:
return artists

@ -39,8 +39,8 @@ def _get_min_api_interval():
val = config_manager.get('spotify.min_api_interval', None)
if val is not None:
return max(0.1, float(val)) # Floor at 100ms to prevent abuse
except Exception:
pass
except Exception as e:
logger.debug("get min_api_interval setting: %s", e)
return MIN_API_INTERVAL
# Request queuing for burst handling
@ -136,8 +136,8 @@ def _set_global_rate_limit(retry_after_seconds, endpoint_name, has_real_header=F
detail=f'{"escalation #" + str(_rate_limit_hit_count) if escalated else "initial"}'
f'{", real Retry-After" if has_real_header else ", estimated"}'
)
except Exception:
pass
except Exception as e:
logger.debug("api_call_tracker record rate_limit_ban: %s", e)
try:
from core.metadata.status import publish_spotify_status
@ -148,8 +148,8 @@ def _set_global_rate_limit(retry_after_seconds, endpoint_name, has_real_header=F
rate_limit=_get_rate_limit_info(),
post_ban_cooldown=_get_post_ban_cooldown_remaining() or None,
)
except Exception:
pass
except Exception as e:
logger.debug("publish_spotify_status set rate limit: %s", e)
def _is_globally_rate_limited():
@ -230,8 +230,8 @@ def _clear_rate_limit():
rate_limit=None,
post_ban_cooldown=None,
)
except Exception:
pass
except Exception as e:
logger.debug("publish_spotify_status clear rate limit: %s", e)
def _detect_and_set_rate_limit(exception, endpoint_name="unknown"):
@ -637,8 +637,8 @@ class SpotifyClient:
rate_limit=_get_rate_limit_info(),
post_ban_cooldown=_get_post_ban_cooldown_remaining() or None,
)
except Exception:
pass
except Exception as e:
logger.debug("publish_spotify_status no-client: %s", e)
return False
# If globally rate limited, report as NOT authenticated so callers
@ -655,8 +655,8 @@ class SpotifyClient:
rate_limit=_get_rate_limit_info(),
post_ban_cooldown=_get_post_ban_cooldown_remaining() or None,
)
except Exception:
pass
except Exception as e:
logger.debug("publish_spotify_status rate-limited: %s", e)
return False
# Post-ban cooldown: after a ban expires, don't probe Spotify immediately.
@ -675,8 +675,8 @@ class SpotifyClient:
rate_limit=None,
post_ban_cooldown=remaining or None,
)
except Exception:
pass
except Exception as e:
logger.debug("publish_spotify_status post-ban cooldown: %s", e)
return False
# Check cache first (lock only for brief read)
@ -692,8 +692,8 @@ class SpotifyClient:
rate_limit=None,
post_ban_cooldown=None,
)
except Exception:
pass
except Exception as e:
logger.debug("publish_spotify_status cache hit: %s", e)
return self._auth_cached_result
# Cache miss — make API call outside the lock.
@ -718,11 +718,11 @@ class SpotifyClient:
rate_limit=None,
post_ban_cooldown=None,
)
except Exception:
pass
except Exception as e:
logger.debug("publish_spotify_status no-token: %s", e)
return False
except Exception:
pass
except Exception as e:
logger.debug("cached token probe: %s", e)
# Use a dedicated probe client (retries=0) so a 429 here propagates
# immediately and we can detect long Retry-After bans.
@ -771,8 +771,8 @@ class SpotifyClient:
rate_limit=_get_rate_limit_info() if rate_limited_state else None,
post_ban_cooldown=None,
)
except Exception:
pass
except Exception as e:
logger.debug("publish_spotify_status auth probe: %s", e)
return result
@ -793,8 +793,8 @@ class SpotifyClient:
rate_limit=None,
post_ban_cooldown=None,
)
except Exception:
pass
except Exception as e:
logger.debug("publish_spotify_status disconnect: %s", e)
cache_path = 'config/.spotify_cache'
try:
@ -1245,8 +1245,8 @@ class SpotifyClient:
for raw in cached_results:
try:
tracks.append(Track.from_spotify_track(raw))
except Exception:
pass
except Exception as e:
logger.debug("Track.from_spotify_track cache parse: %s", e)
if tracks:
return tracks
@ -1298,8 +1298,8 @@ class SpotifyClient:
for raw in cached_results:
try:
artists.append(Artist.from_spotify_artist(raw))
except Exception:
pass
except Exception as e:
logger.debug("Artist.from_spotify_artist cache parse: %s", e)
if artists:
query_lower = query.lower().strip()
artists.sort(key=lambda a: (0 if a.name.lower().strip() == query_lower else 1))
@ -1361,8 +1361,8 @@ class SpotifyClient:
for raw in cached_results:
try:
albums.append(Album.from_spotify_album(raw))
except Exception:
pass
except Exception as e:
logger.debug("Album.from_spotify_album cache parse: %s", e)
if albums:
return albums

@ -640,8 +640,8 @@ class TidalClient:
image_id = image_rel.get('id', '')
if image_id:
image_url = f"https://resources.tidal.com/images/{image_id.replace('-', '/')}/640x640.jpg"
except Exception:
pass
except Exception as _e:
logger.debug("tidal v2 playlists image_url extract: %s", _e)
new_playlist = Playlist(
id=str(playlist_id),
@ -1188,8 +1188,8 @@ class TidalClient:
image_id = image_rel.get('id', '')
if image_id:
playlist.image_url = f"https://resources.tidal.com/images/{image_id.replace('-', '/')}/640x640.jpg"
except Exception:
pass
except Exception as _e:
logger.debug("tidal playlist image_url extract: %s", _e)
logger.info(f"Retrieved Tidal playlist '{playlist.name}' with {len(tracks)} tracks")
return playlist

Loading…
Cancel
Save