Surface silent exceptions in watchlist + discovery + reorganize — 18 sites

- watchlist_scanner.py: 6 sites
- discovery/playlist.py: 5 sites
- discovery/sync.py: 4 sites
- watchlist/auto_scan.py: 1 site (1 left silent — finally-block scanner cleanup)
- library_reorganize.py: 2 sites (4 left silent — all in finally blocks:
  conn.close, staging rmtree, sidecar delete, cleanup_empty_dir)

All non-finally sites converted to `logger.debug("...: %s", e)`.
Finally-block sites kept silent because logger calls during cleanup
(after exception was already raised) can themselves raise.

Refs #369
This commit is contained in:
Broque Thomas 2026-05-07 09:52:20 -07:00
parent de348981a5
commit 8dc9f79f97
5 changed files with 36 additions and 36 deletions

View file

@ -196,8 +196,8 @@ def run_playlist_discovery_worker(playlists, automation_id=None, deps: PlaylistD
current_item=track_name,
log_line=f'{track_name}{cached_match.get("name", "?")} (cache)', log_type='success')
continue
except Exception:
pass
except Exception as e:
logger.debug("discovery cache lookup failed: %s", e)
# Step 2: Generate search queries
try:
@ -252,8 +252,8 @@ def run_playlist_discovery_worker(playlists, automation_id=None, deps: PlaylistD
if match and confidence > best_confidence:
best_confidence = confidence
best_match = match
except Exception:
pass
except Exception as e:
logger.debug("extended discovery search failed: %s", e)
# Step 4: Store results
if best_match and best_confidence >= min_confidence:
@ -290,8 +290,8 @@ def run_playlist_discovery_worker(playlists, automation_id=None, deps: PlaylistD
if _raw:
track_number = _raw.get('track_number')
disc_number = _raw.get('disc_number')
except Exception:
pass
except Exception as e:
logger.debug("metadata cache lookup for album enrichment failed: %s", e)
matched_data = {
'id': best_match.id if hasattr(best_match, 'id') else '',
@ -323,8 +323,8 @@ def run_playlist_discovery_worker(playlists, automation_id=None, deps: PlaylistD
best_confidence, matched_data,
track_name, artist_name
)
except Exception:
pass
except Exception as e:
logger.debug("save discovery cache match failed: %s", e)
logger.info(f"[{i+1}/{len(undiscovered_tracks)}] {track_name}{matched_data['name']} ({best_confidence:.2f})")
deps.update_automation_progress(automation_id,
@ -366,8 +366,8 @@ def run_playlist_discovery_worker(playlists, automation_id=None, deps: PlaylistD
'failed_count': str(total_failed),
'skipped_count': str(total_skipped),
})
except Exception:
pass
except Exception as e:
logger.debug("discovery_completed emit failed: %s", e)
logger.error(f"Playlist discovery complete: {total_discovered} discovered, {total_failed} failed, {total_skipped} skipped")
deps.update_automation_progress(automation_id, status='finished', progress=100,

View file

@ -290,8 +290,8 @@ def run_sync_task(playlist_id, playlist_name, tracks_json, automation_id=None, p
logger.debug(f"Sync cache hit: '{original_title}' → server track {cached['server_track_id']}")
return DatabaseTrackCached(db_track_check), cached['confidence']
logger.warning(f"Sync cache stale for '{original_title}' — track gone")
except Exception:
pass
except Exception as e:
logger.debug("sync match cache fast-path failed: %s", e)
# --- End cache fast-path ---
# Try each artist (same logic as original)
@ -322,8 +322,8 @@ def run_sync_task(playlist_id, playlist_name, tracks_json, automation_id=None, p
spotify_id, me.clean_title(original_title), me.clean_artist(artist_name),
active_server, db_track.id, db_track.title, confidence
)
except Exception:
pass
except Exception as e:
logger.debug("save sync match cache failed: %s", e)
# Create mock track object for playlist creation
class DatabaseTrackMock:
@ -429,8 +429,8 @@ def run_sync_task(playlist_id, playlist_name, tracks_json, automation_id=None, p
entry = db.get_sync_history_entry(_resync_entry_id)
if entry:
target_batch_id = entry.get('batch_id', sync_batch_id)
except Exception:
pass
except Exception as e:
logger.debug("resync history lookup failed: %s", e)
else:
db.update_sync_history_completion(sync_batch_id, matched, synced, failed)
@ -466,8 +466,8 @@ def run_sync_task(playlist_id, playlist_name, tracks_json, automation_id=None, p
'synced_tracks': str(getattr(result, 'synced_tracks', 0)),
'failed_tracks': str(getattr(result, 'failed_tracks', 0)),
})
except Exception:
pass
except Exception as e:
logger.debug("playlist_synced emit failed: %s", e)
# Save sync status with match counts and track hash for smart-skip on next scheduled sync
import hashlib as _hl

View file

@ -938,8 +938,8 @@ class _RunContext:
return
try:
self.on_progress(updates)
except Exception:
pass
except Exception as e:
logger.debug("progress emit failed: %s", e)
def record_error(self, track_id, title, message, kind: str = 'skipped') -> None:
with self.state_lock:
@ -1185,8 +1185,8 @@ def reorganize_album(
return
try:
on_progress(updates)
except Exception:
pass
except Exception as e:
logger.debug("reorganize progress callback failed: %s", e)
# Load album + tracks
album_data, tracks = load_album_and_tracks(db, album_id)

View file

@ -440,8 +440,8 @@ def process_watchlist_scan_automatically(automation_id=None, profile_id=None, de
'new_tracks_found': str(total_new_tracks),
'tracks_added': str(total_added_to_wishlist),
})
except Exception:
pass
except Exception as e:
logger.debug("watchlist_scan_completed emit failed: %s", e)
except Exception as e:
logger.error(f"Error in automatic watchlist scan: {e}")

View file

@ -2745,8 +2745,8 @@ class WatchlistScanner:
if release_date_str and len(release_date_str) >= 10:
release_date = datetime.strptime(release_date_str[:10], "%Y-%m-%d")
is_new = (datetime.now() - release_date).days <= 30
except Exception:
pass
except Exception as e:
logger.debug("album release_date parse failed: %s", e)
for track in tracks:
try:
@ -2778,8 +2778,8 @@ class WatchlistScanner:
synth_pop += 15
elif age_days <= 365:
synth_pop += 5
except Exception:
pass
except Exception as e:
logger.debug("synthetic popularity age calc failed: %s", e)
if similar_artist.occurrence_count >= 3:
synth_pop += 10
elif similar_artist.occurrence_count >= 2:
@ -2902,8 +2902,8 @@ class WatchlistScanner:
if release_date_str and len(release_date_str) >= 10:
release_date = datetime.strptime(release_date_str[:10], "%Y-%m-%d")
is_new = (datetime.now() - release_date).days <= 30
except Exception:
pass
except Exception as e:
logger.debug("album release_date parse failed: %s", e)
for track in tracks:
try:
@ -3214,8 +3214,8 @@ class WatchlistScanner:
elif profile['avg_daily_plays'] > 20:
days_lookback = 21 # Heavy listener — keep it fresh
logger.info(f"Recent albums window: {days_lookback} days (avg {profile['avg_daily_plays']:.1f} plays/day)")
except Exception:
pass
except Exception as e:
logger.debug("listening profile lookback adjust failed: %s", e)
cutoff_date = datetime.now() - timedelta(days=days_lookback)
discovery_sources = self._discovery_source_priority()
if not discovery_sources:
@ -3498,8 +3498,8 @@ class WatchlistScanner:
_artist_genre_cache[_row[0].lower()] = {g.strip().lower() for g in _row[1].split(',') if g.strip()}
_conn.close()
logger.debug(f"Built genre cache for {len(_artist_genre_cache)} artists")
except Exception:
pass
except Exception as e:
logger.debug("artist genre cache build failed: %s", e)
logger.info(f"Curating playlists for sources: {sources_to_process}")
@ -3760,8 +3760,8 @@ class WatchlistScanner:
_wa_list = self.database.get_watchlist_artists(profile_id=profile_id)
for _wa in _wa_list:
_wa_id_to_name[str(_wa.id)] = (_wa.artist_name or '').lower()
except Exception:
pass
except Exception as e:
logger.debug("watchlist artist id-to-name map failed: %s", e)
all_similar = self.database.get_top_similar_artists(limit=200, profile_id=profile_id)