Files
AeroFetch/src/renderer/src/reportError.ts
T
debont80 519e522917 feat(main): CC8 — file-backed leveled logger + renderer log sink
Diagnostics were invisible in a packaged build: main catches did a bare
console.error (DevTools suppressed in prod, M31) and the renderer's logError
(M29) wrote to an unreachable console. Add a small leveled logger
(src/main/logger.ts) appending to <userData>/logs/aerofetch.log with size-capped
rotation; all app/fs access is lazy+guarded so it's a safe no-op under tests.

- Route the 5 main-process console.* catch sites (jsonStore write-fail, settings
  write-fail + plaintext-secret warn, cookie loadURL, yt-dlp auto-update)
  through the logger.
- Add a fire-and-forget log:write IPC channel + preload logError() so the
  renderer's logError forwards failures to the main file sink (closes the M29
  "sink" half the code comments deferred to CC8). mockApi + Api type updated.
- Unit-test pure formatLine/composeMessage + no-op safety; update the R6
  jsonStore test to assert against the logger.

The user-facing toast half of CC8 ties to the global status surface (UI25/UX9).
typecheck + 258 tests + lint + prettier green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 08:53:06 -04:00

22 lines
1.1 KiB
TypeScript

// Centralized handler for fire-and-forget IPC (and similar async) calls whose
// failure we want recorded but can't surface to the user — the optimistic store
// update has already happened, so there's nothing to roll back or prompt about.
// Replaces the swallowed `.catch(() => {})` sites the audit flagged (M29) with a
// single, consistent log format. `op` names the operation, e.g. 'addHistory'.
//
// The failure is both printed to the renderer console (dev/`--inspect`) and
// forwarded to the main process's file-backed diagnostic log (CC8), so it survives
// into a packaged build where the renderer console is unreachable.
export function logError(op: string): (e: unknown) => void {
return (e) => {
console.error(`[AeroFetch] ${op} failed:`, e)
try {
const detail = e instanceof Error ? e.message : String(e)
// window.api is absent in the browser UI preview and in unit tests.
if (typeof window !== 'undefined') window.api?.logError?.(op, detail)
} catch {
/* logging must never throw out of a catch handler */
}
}
}