Archilyzer · Source

archilyzer

Archilyzer
git clone https://archilyzer.pages.dev/source/archilyzer.git
Log | Files | Refs | README | LICENSE

commit de710a7fc6aee9043f3bd2451e56bda79e06701a
parent e45b36b6deedca7a81b08928fbf7f91d90b676a8
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date:   Sun, 20 Sep 2026 03:15:23 -0400

metadata scan: a failed run says so in the store, and names the real failure

A fatal throw escaped before the `lastRun` write, so `stopped: "error"` was
never persisted: the job failed while the store still said the last run
finished cleanly, and the UI had nothing to show for it. The run record is now
written in the finally, best-effort — a store this cannot write is not a reason
to replace the real error with a second one — and rewritten afterwards for the
verdict that is only decided later (a block that survives its cookie retry).

`yt-dlp exited with code undefined` was what the operator saw when yt-dlp could
not be SPAWNED at all, which is the most likely cause of a total failure and
the one that message helped with least. execa knows the difference, so the
message now uses `shortMessage` when the process failed to run.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

Diffstat:
Mcommon/ytdlp/metadataScan.ts | 35++++++++++++++++++++++++++++++++++-
1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/common/ytdlp/metadataScan.ts b/common/ytdlp/metadataScan.ts @@ -542,7 +542,12 @@ export async function runMetadataScan( Object.keys(errors).length === 0 ) { stopped = "error"; - stoppedMessage = `yt-dlp exited with code ${result.exitCode}`; + // `exited with code undefined` is what this said when yt-dlp could not be + // SPAWNED at all — a missing binary, the single most likely cause — which + // told the operator nothing. execa knows the difference. + stoppedMessage = result.failed + ? result.shortMessage + : `yt-dlp exited with code ${result.exitCode}`; throw new Error(stoppedMessage); } }; @@ -600,6 +605,30 @@ export async function runMetadataScan( } finally { await flush(true); await rm(tmpRoot, { recursive: true, force: true }); + // THE RUN RECORD IS WRITTEN HERE, not after the happy path. A fatal throw + // used to escape before it, so `stopped: "error"` was never persisted: the + // job failed, the store still said the last run finished cleanly, and the + // UI had nothing to show for it. Best-effort — a store this cannot write is + // not a reason to replace the real error with a second one. + try { + await upsertMetadataScan( + paths, + slug, + { + lastRun: { + startedAt, + finishedAt: new Date().toISOString(), + scanned: scannedTotal, + errors: Object.keys(errors).length, + ...(stopped ? { stopped } : {}), + ...(stoppedMessage ? { message: stoppedMessage } : {}), + }, + }, + new Date().toISOString(), + ); + } catch { + /* the thrown error, if any, is the one worth reporting */ + } } // A block that survived (or never had) a cookie retry is the source refusing @@ -617,6 +646,10 @@ export async function runMetadataScan( } const errorCount = Object.keys(errors).length; + // Rewritten because `stopped` may only have been DECIDED above (a block that + // survived its cookie retry becomes a stop after the finally has run). The + // finally's write is the one that survives a throw; this is the one that + // carries the verdict. await upsertMetadataScan( paths, slug,