From 821977130471a163fdfd2fce519055915549bb81 Mon Sep 17 00:00:00 2001 From: Broque Thomas <26755000+Nezreka@users.noreply.github.com> Date: Thu, 7 May 2026 10:27:04 -0700 Subject: [PATCH] =?UTF-8?q?Add=20module=20logger=20+=20surface=20silent=20?= =?UTF-8?q?exceptions=20in=207=20logger-less=20files=20=E2=80=94=2012=20si?= =?UTF-8?q?tes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These files had silent `except Exception: pass` blocks but no module logger. Added `import logging` + `logger = logging.getLogger(__name__)` at the top of each, then replaced the silent excepts with `logger.debug(...)`. - core/replaygain.py — 4 sites (id3 txxx + vorbis + mp4 atom reads) - core/wishlist/presence.py — 3 sites (wishlist row parsing + queries) - core/runtime_state.py — 1 site (activity toast emit) - core/automation/signals.py — 1 site (collect known signals) - core/download_engine/rate_limit.py — 1 site (plugin rate_limit_policy) - api/system.py — 1 site (hydrabase status probe) - api/search.py — 1 site (hydrabase search) Refs #369 --- api/search.py | 8 ++++++-- api/system.py | 7 +++++-- core/automation/signals.py | 7 +++++-- core/download_engine/rate_limit.py | 7 +++++-- core/replaygain.py | 19 +++++++++++-------- core/runtime_state.py | 7 +++++-- core/wishlist/presence.py | 15 +++++++++------ 7 files changed, 46 insertions(+), 24 deletions(-) diff --git a/api/search.py b/api/search.py index 48a237c7..c2290fd3 100644 --- a/api/search.py +++ b/api/search.py @@ -2,10 +2,14 @@ Search endpoints — search external sources (Spotify, iTunes, Hydrabase). """ +import logging + from flask import request, current_app from .auth import require_api_key from .helpers import api_success, api_error +logger = logging.getLogger(__name__) + def register_routes(bp): @@ -38,8 +42,8 @@ def register_routes(bp): if hydra_results: tracks = [_serialize_track(t) for t in hydra_results] return api_success({"tracks": tracks, "source": "hydrabase"}) - except Exception: - pass + except Exception as e: + logger.debug("hydrabase search failed: %s", e) spotify = ctx.get("spotify_client") from core.metadata_service import get_primary_source, get_primary_client diff --git a/api/system.py b/api/system.py index d561cc19..c462d5f1 100644 --- a/api/system.py +++ b/api/system.py @@ -2,12 +2,15 @@ System endpoints — status, activity feed, stats. """ +import logging import time from flask import current_app from .auth import require_api_key from .helpers import api_success, api_error +logger = logging.getLogger(__name__) + def register_routes(bp): @@ -35,8 +38,8 @@ def register_routes(bp): try: ws, _ = hydrabase.get_ws_and_lock() hydrabase_ok = ws is not None and ws.connected - except Exception: - pass + except Exception as e: + logger.debug("hydrabase status probe failed: %s", e) return api_success({ "uptime": f"{hours}h {minutes}m {seconds}s", diff --git a/core/automation/signals.py b/core/automation/signals.py index a9ce9214..9b82c5a1 100644 --- a/core/automation/signals.py +++ b/core/automation/signals.py @@ -8,6 +8,9 @@ names from the saved automation set so the builder UI can autocomplete. from __future__ import annotations import json +import logging + +logger = logging.getLogger(__name__) def collect_known_signals(database) -> list[str]: @@ -38,6 +41,6 @@ def collect_known_signals(database) -> list[str]: signals.add(sig) except (json.JSONDecodeError, TypeError): pass - except Exception: - pass + except Exception as e: + logger.debug("collect known signals failed: %s", e) return sorted(signals) diff --git a/core/download_engine/rate_limit.py b/core/download_engine/rate_limit.py index 57b86642..65d33c86 100644 --- a/core/download_engine/rate_limit.py +++ b/core/download_engine/rate_limit.py @@ -22,8 +22,11 @@ module-level constant in the client file. from __future__ import annotations +import logging from dataclasses import dataclass +logger = logging.getLogger(__name__) + @dataclass(frozen=True) class RateLimitPolicy: @@ -63,8 +66,8 @@ def resolve_policy(plugin) -> RateLimitPolicy: policy = method() if isinstance(policy, RateLimitPolicy): return policy - except Exception: - pass + except Exception as e: + logger.debug("plugin rate_limit_policy() call failed: %s", e) declared = getattr(plugin, 'RATE_LIMIT_POLICY', None) if isinstance(declared, RateLimitPolicy): diff --git a/core/replaygain.py b/core/replaygain.py index a10469df..22e25c17 100644 --- a/core/replaygain.py +++ b/core/replaygain.py @@ -7,10 +7,13 @@ Tag writing uses mutagen directly to stay consistent with the rest of the codeba Supported formats: MP3, FLAC, OGG Vorbis, Opus, M4A/MP4 """ +import logging import re import subprocess from typing import Optional, Tuple, Dict +logger = logging.getLogger(__name__) + # ReplayGain 2.0 reference level (EBU R128) RG_REFERENCE_LUFS = -18.0 @@ -189,8 +192,8 @@ def read_replaygain_tags(file_path: str) -> Dict[str, Optional[str]]: result['track_peak'] = _mp4_rg(audio, _TAG_TRACK_PEAK) result['album_gain'] = _mp4_rg(audio, _TAG_ALBUM_GAIN) result['album_peak'] = _mp4_rg(audio, _TAG_ALBUM_PEAK) - except Exception: - pass + except Exception as e: + logger.debug("read replaygain tags failed: %s", e) return result @@ -207,8 +210,8 @@ def _read_id3_txxx(audio, description: str) -> Optional[str]: if frame_key.upper() == key.upper(): frame = audio.tags[frame_key] return str(frame.text[0]) if frame.text else None - except Exception: - pass + except Exception as e: + logger.debug("read id3 txxx frame failed: %s", e) return None @@ -218,8 +221,8 @@ def _vorbis_first(audio, key: str) -> Optional[str]: vals = audio.get(key) or audio.get(key.upper()) if vals: return str(vals[0]) - except Exception: - pass + except Exception as e: + logger.debug("read vorbis comment failed: %s", e) return None @@ -234,8 +237,8 @@ def _mp4_rg(audio, tag_name: str) -> Optional[str]: if hasattr(val, 'decode'): return val.decode('utf-8') return str(val) - except Exception: - pass + except Exception as e: + logger.debug("read mp4 replaygain atom failed: %s", e) return None diff --git a/core/runtime_state.py b/core/runtime_state.py index f952aee1..dfa11798 100644 --- a/core/runtime_state.py +++ b/core/runtime_state.py @@ -2,11 +2,14 @@ from __future__ import annotations +import logging import threading import time from functools import wraps from typing import Any, Dict, Optional +logger = logging.getLogger(__name__) + matched_context_lock = threading.Lock() matched_downloads_context: Dict[str, Dict[str, Any]] = {} tasks_lock = threading.Lock() @@ -57,8 +60,8 @@ def add_activity_item(icon, title, subtitle, time_ago="Now", show_toast=True): if show_toast and _activity_toast_emitter is not None: try: _activity_toast_emitter("dashboard:toast", activity_item) - except Exception: - pass + except Exception as e: + logger.debug("emit activity toast failed: %s", e) return activity_item diff --git a/core/wishlist/presence.py b/core/wishlist/presence.py index 16eddc2b..f7b9cee1 100644 --- a/core/wishlist/presence.py +++ b/core/wishlist/presence.py @@ -3,6 +3,9 @@ from __future__ import annotations import json +import logging + +logger = logging.getLogger(__name__) def load_wishlist_keys(cursor, profile_id: int) -> set[str]: @@ -27,21 +30,21 @@ def load_wishlist_keys(cursor, profile_id: int) -> set[str]: wa = "" if wname: keys.add(wname + "|||" + wa.lower().strip()) - except Exception: - pass + except Exception as e: + logger.debug("parse wishlist row failed: %s", e) try: cursor.execute("SELECT spotify_data FROM wishlist_tracks WHERE profile_id = ?", (profile_id,)) _absorb(cursor.fetchall()) return keys - except Exception: - pass + except Exception as e: + logger.debug("profile-aware wishlist query failed: %s", e) try: cursor.execute("SELECT spotify_data FROM wishlist_tracks") _absorb(cursor.fetchall()) - except Exception: - pass + except Exception as e: + logger.debug("legacy wishlist query failed: %s", e) return keys