Surface silent exceptions in music_database.py — 18 sites

Mostly schema-migration ALTER TABLE fallbacks (column-already-exists
is the silent expected case) plus a few cache-purge/notify-migration
spots. Same pattern as the web_server sweep: `except Exception as e:
logger.debug("...: %s", e)`.

Refs #369
This commit is contained in:
Broque Thomas 2026-05-07 09:17:19 -07:00
parent b0c58a0f91
commit bfef2c7579

View file

@ -650,8 +650,8 @@ class MusicDatabase:
try: try:
cursor.execute("ALTER TABLE sync_history ADD COLUMN track_results TEXT") cursor.execute("ALTER TABLE sync_history ADD COLUMN track_results TEXT")
logger.info("Added track_results column to sync_history table") logger.info("Added track_results column to sync_history table")
except Exception: except Exception as e:
pass logger.debug("Failed to add track_results column: %s", e)
# Migration: add source_page column to sync_history (UI origin context for batch panel) # Migration: add source_page column to sync_history (UI origin context for batch panel)
try: try:
@ -660,8 +660,8 @@ class MusicDatabase:
try: try:
cursor.execute("ALTER TABLE sync_history ADD COLUMN source_page TEXT") cursor.execute("ALTER TABLE sync_history ADD COLUMN source_page TEXT")
logger.info("Added source_page column to sync_history table") logger.info("Added source_page column to sync_history table")
except Exception: except Exception as e:
pass logger.debug("Failed to add source_page column: %s", e)
# Migration: add track_artist column for per-track artist on compilations/DJ mixes # Migration: add track_artist column for per-track artist on compilations/DJ mixes
try: try:
@ -670,8 +670,8 @@ class MusicDatabase:
try: try:
cursor.execute("ALTER TABLE tracks ADD COLUMN track_artist TEXT") cursor.execute("ALTER TABLE tracks ADD COLUMN track_artist TEXT")
logger.info("Added track_artist column to tracks table") logger.info("Added track_artist column to tracks table")
except Exception: except Exception as e:
pass logger.debug("Failed to add track_artist column: %s", e)
# Migration: add file_size column so the Stats page can show # Migration: add file_size column so the Stats page can show
# total library size on disk without having to walk the # total library size on disk without having to walk the
@ -687,8 +687,8 @@ class MusicDatabase:
try: try:
cursor.execute("ALTER TABLE tracks ADD COLUMN file_size INTEGER") cursor.execute("ALTER TABLE tracks ADD COLUMN file_size INTEGER")
logger.info("Added file_size column to tracks table") logger.info("Added file_size column to tracks table")
except Exception: except Exception as e:
pass logger.debug("Failed to add file_size column: %s", e)
# One-time migration: purge discovery cache entries that lack track_number. # One-time migration: purge discovery cache entries that lack track_number.
# Prior versions cached discovery results without track_number/disc_number/release_date, # Prior versions cached discovery results without track_number/disc_number/release_date,
@ -704,8 +704,8 @@ class MusicDatabase:
cursor.execute("CREATE TABLE _discovery_cache_v2_migrated (applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP)") cursor.execute("CREATE TABLE _discovery_cache_v2_migrated (applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP)")
if purged > 0: if purged > 0:
logger.info(f"Purged {purged} stale discovery cache entries (missing track_number)") logger.info(f"Purged {purged} stale discovery cache entries (missing track_number)")
except Exception: except Exception as e:
pass logger.debug("Failed to purge stale discovery cache entries: %s", e)
# One-time migration: purge Deezer album/track cache entries with missing data. # One-time migration: purge Deezer album/track cache entries with missing data.
# Deezer's /artist/{id}/albums returns albums without artist info, and search # Deezer's /artist/{id}/albums returns albums without artist info, and search
@ -721,8 +721,8 @@ class MusicDatabase:
cursor.execute("CREATE TABLE _deezer_cache_v2_migrated (applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP)") cursor.execute("CREATE TABLE _deezer_cache_v2_migrated (applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP)")
if purged > 0: if purged > 0:
logger.info(f"Purged {purged} stale Deezer cache entries (missing artist/track_position)") logger.info(f"Purged {purged} stale Deezer cache entries (missing artist/track_position)")
except Exception: except Exception as e:
pass logger.debug("Failed to purge stale Deezer cache entries: %s", e)
# One-time migration: purge cached tracks/albums with junk artist names. # One-time migration: purge cached tracks/albums with junk artist names.
# The cache gate now rejects these, but existing entries need cleaning. # The cache gate now rejects these, but existing entries need cleaning.
@ -738,8 +738,8 @@ class MusicDatabase:
cursor.execute("CREATE TABLE _cache_junk_artist_purged (applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP)") cursor.execute("CREATE TABLE _cache_junk_artist_purged (applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP)")
if purged > 0: if purged > 0:
logger.info(f"Purged {purged} cached tracks/albums with junk artist names") logger.info(f"Purged {purged} cached tracks/albums with junk artist names")
except Exception: except Exception as e:
pass logger.debug("Failed to purge cached tracks/albums with junk artist names: %s", e)
# HiFi API instances table # HiFi API instances table
cursor.execute(""" cursor.execute("""
@ -819,8 +819,8 @@ class MusicDatabase:
config = json.loads(row[2]) if row[2] else {} config = json.loads(row[2]) if row[2] else {}
then_actions = json.dumps([{'type': row[1], 'config': config}]) then_actions = json.dumps([{'type': row[1], 'config': config}])
cursor.execute("UPDATE automations SET then_actions = ? WHERE id = ?", (then_actions, row[0])) cursor.execute("UPDATE automations SET then_actions = ? WHERE id = ?", (then_actions, row[0]))
except Exception: except Exception as e:
pass logger.debug("Failed to migrate notify data for automation row: %s", e)
logger.info("Migrated existing notify data to then_actions") logger.info("Migrated existing notify data to then_actions")
except Exception as e: except Exception as e:
logger.error(f"Error adding automation then_actions column: {e}") logger.error(f"Error adding automation then_actions column: {e}")
@ -1527,8 +1527,8 @@ class MusicDatabase:
try: try:
cursor.execute("ALTER TABLE liked_albums_pool ADD COLUMN discogs_release_id TEXT") cursor.execute("ALTER TABLE liked_albums_pool ADD COLUMN discogs_release_id TEXT")
logger.info("Added discogs_release_id column to liked_albums_pool") logger.info("Added discogs_release_id column to liked_albums_pool")
except Exception: except Exception as e:
pass logger.debug("Failed to add discogs_release_id column: %s", e)
logger.info("Discovery tables added/verified successfully") logger.info("Discovery tables added/verified successfully")
@ -2468,8 +2468,8 @@ class MusicDatabase:
if 'profile_id' not in columns: if 'profile_id' not in columns:
cursor.execute(f"ALTER TABLE {table} ADD COLUMN profile_id INTEGER DEFAULT 1") cursor.execute(f"ALTER TABLE {table} ADD COLUMN profile_id INTEGER DEFAULT 1")
logger.info(f"Repaired missing profile_id column on {table}") logger.info(f"Repaired missing profile_id column on {table}")
except Exception: except Exception as e:
pass logger.debug("Failed to repair profile_id column on %s: %s", table, e)
if already_migrated: if already_migrated:
return # Rest of migration already done return # Rest of migration already done
@ -2666,8 +2666,8 @@ class MusicDatabase:
for idx_name, table in index_pairs: for idx_name, table in index_pairs:
try: try:
cursor.execute(f"CREATE INDEX IF NOT EXISTS {idx_name} ON {table} (profile_id)") cursor.execute(f"CREATE INDEX IF NOT EXISTS {idx_name} ON {table} (profile_id)")
except Exception: except Exception as e:
pass logger.debug("Failed to create index %s on %s: %s", idx_name, table, e)
# Set migration marker # Set migration marker
cursor.execute(""" cursor.execute("""
@ -3326,8 +3326,8 @@ class MusicDatabase:
)) ))
if cursor.rowcount > 0: if cursor.rowcount > 0:
inserted += 1 inserted += 1
except Exception: except Exception as e:
pass logger.debug("Failed to insert listening event: %s", e)
conn.commit() conn.commit()
return inserted return inserted
except Exception as e: except Exception as e:
@ -3635,8 +3635,8 @@ class MusicDatabase:
total_size = 0 total_size = 0
try: try:
total_size = os.path.getsize(str(self.database_path)) total_size = os.path.getsize(str(self.database_path))
except Exception: except Exception as e:
pass logger.debug("Failed to stat database file size: %s", e)
conn = self._get_connection() conn = self._get_connection()
cursor = conn.cursor() cursor = conn.cursor()
@ -3663,8 +3663,8 @@ class MusicDatabase:
cursor.execute(f"SELECT COUNT(*) FROM [{tbl}]") cursor.execute(f"SELECT COUNT(*) FROM [{tbl}]")
count = cursor.fetchone()[0] count = cursor.fetchone()[0]
tables.append({'name': tbl, 'size': count}) tables.append({'name': tbl, 'size': count})
except Exception: except Exception as e:
pass logger.debug("Failed to get row count for table %s: %s", tbl, e)
tables.sort(key=lambda x: x['size'], reverse=True) tables.sort(key=lambda x: x['size'], reverse=True)
return { return {
@ -4189,8 +4189,8 @@ class MusicDatabase:
'bubble_snapshots', 'recent_releases']: 'bubble_snapshots', 'recent_releases']:
try: try:
cursor.execute(f"DELETE FROM {table} WHERE profile_id = ?", (profile_id,)) cursor.execute(f"DELETE FROM {table} WHERE profile_id = ?", (profile_id,))
except Exception: except Exception as e:
pass logger.debug("Failed to delete from %s for profile: %s", table, e)
cursor.execute("DELETE FROM profiles WHERE id = ?", (profile_id,)) cursor.execute("DELETE FROM profiles WHERE id = ?", (profile_id,))
conn.commit() conn.commit()
return cursor.rowcount > 0 return cursor.rowcount > 0
@ -5152,8 +5152,8 @@ class MusicDatabase:
album_artist_name = artist_row[0] if artist_row else '' album_artist_name = artist_row[0] if artist_row else ''
if nav_artist and nav_artist.lower() != album_artist_name.lower(): if nav_artist and nav_artist.lower() != album_artist_name.lower():
track_artist = nav_artist track_artist = nav_artist
except Exception: except Exception as e:
pass logger.debug("Failed to load album artist for track_artist comparison: %s", e)
# Extract MusicBrainz recording ID from server if available (Navidrome provides this) # Extract MusicBrainz recording ID from server if available (Navidrome provides this)
mbid = getattr(track_obj, 'musicBrainzId', None) or None mbid = getattr(track_obj, 'musicBrainzId', None) or None
@ -10901,8 +10901,8 @@ class MusicDatabase:
""") """)
for row in cursor.fetchall(): for row in cursor.fetchall():
source_counts[row['download_source']] = row['cnt'] source_counts[row['download_source']] = row['cnt']
except Exception: except Exception as e:
pass logger.debug("Failed to load library history source counts: %s", e)
stats['source_counts'] = source_counts stats['source_counts'] = source_counts
return stats return stats
@ -11193,8 +11193,8 @@ class MusicDatabase:
WHERE playlist_id = ? AND source_track_id IS NOT NULL AND extra_data IS NOT NULL WHERE playlist_id = ? AND source_track_id IS NOT NULL AND extra_data IS NOT NULL
""", (playlist_id,)) """, (playlist_id,))
old_extra_map = {row['source_track_id']: row['extra_data'] for row in cursor.fetchall()} old_extra_map = {row['source_track_id']: row['extra_data'] for row in cursor.fetchall()}
except Exception: except Exception as e:
pass logger.debug("Failed to preserve mirrored playlist extra_data: %s", e)
# Replace all tracks # Replace all tracks
cursor.execute("DELETE FROM mirrored_playlist_tracks WHERE playlist_id=?", (playlist_id,)) cursor.execute("DELETE FROM mirrored_playlist_tracks WHERE playlist_id=?", (playlist_id,))