refactor(logging): route frontend console calls through the logger

TRACES: | DR-204

484 ungated `console.*` calls across 63 non-test frontend files shipped to
end users with no way to turn them off. Mechanical substitution, no control
flow, error handling or message semantics changed:

  console.log / console.debug -> log.debug
  console.info                -> log.info
  console.warn                -> log.warn
  console.error               -> log.error

Hand-written `"[Scope] …"` prefixes are dropped where the logger's scope
now carries them; scope names that already existed are preserved verbatim
(`[Auth]`, `[VideoPlayer]`, `[PiP]`, …) and inferred from the filename
where a file had none. `src/routes/player/[id]/+page.svelte` keeps its
`NextEpisode` and `AutoPlay` sub-scopes as separate loggers rather than
flattening them into the page scope.

`grep -rn 'console\.' src/` now matches nothing outside the tests and the
facade itself.
This commit is contained in:
2026-08-20 19:29:59 +02:00
parent 4c82a0a025
commit d54d8cc7c4
63 changed files with 686 additions and 490 deletions
+18 -15
View File
@@ -20,6 +20,9 @@ import { preloadUpcomingTracks } from "$lib/services/preload";
import { playerController } from "$lib/player";
import type { MediaItem } from "$lib/api/types";
import { get } from "svelte/store";
import { createLogger } from "$lib/utils/logger";
const log = createLogger("playerEvents");
// PlayerStatusEvent and SleepTimerMode are generated by tauri-specta and
// imported from $lib/api/bindings — they are the authoritative shapes emitted
@@ -34,7 +37,7 @@ let isInitialized = false;
*/
export async function initPlayerEvents(): Promise<void> {
if (isInitialized) {
console.warn("Player events already initialized");
log.warn("Player events already initialized");
return;
}
@@ -43,9 +46,9 @@ export async function initPlayerEvents(): Promise<void> {
handlePlayerEvent(event.payload);
});
isInitialized = true;
console.log("Player event listener initialized");
log.debug("Player event listener initialized");
} catch (e) {
console.error("Failed to initialize player events:", e);
log.error("Failed to initialize player events:", e);
}
}
@@ -98,7 +101,7 @@ function handlePlayerEvent(event: PlayerStatusEvent): void {
case "buffering":
// Could show buffering indicator in UI
console.debug(`Buffering: ${event.percent}%`);
log.debug(`Buffering: ${event.percent}%`);
break;
case "error":
@@ -196,7 +199,7 @@ async function handleStateChanged(state: string, _mediaId: string | null): Promi
// When local playback starts, ensure mode is set to local
const mode = get(playbackMode);
if (mode.mode !== "local") {
console.log("Setting playback mode to local");
log.debug("Setting playback mode to local");
playbackMode.setMode("local");
}
@@ -215,7 +218,7 @@ async function handleStateChanged(state: string, _mediaId: string | null): Promi
// Trigger preloading of upcoming tracks in the background
preloadUpcomingTracks().catch((e) => {
// Preload failures are non-critical, already logged in the service
console.debug("[playerEvents] Preload failed (non-critical):", e);
log.debug("Preload failed (non-critical):", e);
});
} else if (state === "paused" && currentItem) {
// Keep current position and duration from store. The same track is
@@ -240,7 +243,7 @@ async function handleStateChanged(state: string, _mediaId: string | null): Promi
// When local playback stops, revert to idle mode
const currentMode = get(playbackMode);
if (currentMode.mode === "local") {
console.log("Setting playback mode to idle");
log.debug("Setting playback mode to idle");
playbackMode.setMode("idle");
}
@@ -254,7 +257,7 @@ async function handleStateChanged(state: string, _mediaId: string | null): Promi
function handleMediaLoaded(duration: number): void {
// Media is now loaded and ready
// The state_changed event will handle setting the playing state
console.debug(`Media loaded, duration: ${duration}s`);
log.debug(`Media loaded, duration: ${duration}s`);
}
/**
@@ -268,7 +271,7 @@ async function handlePlaybackEnded(): Promise<void> {
try {
await commands.playerOnPlaybackEnded(null, null);
} catch (e) {
console.error("[playerEvents] Failed to handle playback ended:", e);
log.error("Failed to handle playback ended:", e);
// Fallback: set idle state on error
player.setIdle();
}
@@ -287,18 +290,18 @@ async function handlePlaybackEnded(): Promise<void> {
* TRACES: UR-004, UR-040 | DR-130
*/
async function handleError(message: string, recoverable: boolean): Promise<void> {
console.error(`Playback error (recoverable: ${recoverable}): ${message}`);
log.error(`Playback error (recoverable: ${recoverable}): ${message}`);
if (recoverable) {
try {
if (await commands.playerRecoverStream()) {
console.log("Stream re-opened after a recoverable error - not stopping");
log.debug("Stream re-opened after a recoverable error - not stopping");
return;
}
} catch (e) {
// Fall through to the normal stop: a failed recovery attempt is still an
// error, and leaving the player running would strand it mid-failure.
console.error("Stream recovery attempt failed:", e);
log.error("Stream recovery attempt failed:", e);
}
}
@@ -308,9 +311,9 @@ async function handleError(message: string, recoverable: boolean): Promise<void>
// This also reports playback stopped to Jellyfin server
try {
await commands.playerStop();
console.log("Backend player stopped after error");
log.debug("Backend player stopped after error");
} catch (e) {
console.error("Failed to stop player after error:", e);
log.error("Failed to stop player after error:", e);
// Continue with state cleanup even if stop fails
}
@@ -359,7 +362,7 @@ function handleControlCommand(action: string, position: number | null): void {
void adapter.pause();
break;
default:
console.warn("[playerEvents] Unknown control command:", action);
log.warn("Unknown control command:", action);
}
}