Skip to content

M23: [Major] Silent catches across scan code make file/perm errors invisible #70

Description

@curtyo18

Summary

Five silent catches in packages/engine/src/scan/ swallow errors with no log. Corrupt images, permission-denied subtrees, MediaInfo crashes, and stat failures all become invisible to operators. Standards file coding-standards.md explicitly flags this pattern as Important: "Silent catches — try { ... } catch { /* nothing */ } or catches that swallow the underlying error without logging, rethrowing, or recovering deliberately."

Sites

  • metadata-image.ts:59-61catch { return blank } for exifr errors. Corrupt/unsupported images become silently null-dated.
  • metadata-video.ts:33-35catch around execFile for mediainfo subprocess. MediaInfo crash or timeout indistinguishable from "no metadata."
  • metadata-video.ts:55-58 — second silent catch around the JSON parse. Malformed mediainfo output is silently dropped.
  • walker.ts:56-60 — silent catch around readdir. Permission-denied subtree leaves no trace; the scan continues as if the directory were empty.
  • walker.ts:80-83 — silent catch around lstat on a symlink target. Broken symlink → silent skip.
  • walker.ts:137-141 — silent catch around lstat on a file. Bad symlink or permission-denied file → silent skip.

Background

From the 2026-05-17 multi-agent full-repo review. These swallow paths are deliberate — the scan should not abort on a single bad file — but the absence of a log line means a user investigating "why isn't this folder in the catalog?" has no breadcrumb to follow.

Acceptance criteria

  • Each site logs at warn level (using the structured logger threaded through scan/orchestrator.ts) with the path, the operation, and the error code/message. Suggested events:
    • metadata-image-error (path, err)
    • metadata-video-error (path, phase: 'execFile'|'parse', err)
    • walker-readdir-error (path, err)
    • walker-stat-error (path, kind: 'symlink'|'file', err)
  • The scan continues on each error (unchanged behavior); the only change is the log line.
  • If the existing Logger interface doesn't accept a { path, err } shape, extend it to accept an optional structured-fields object.
  • Tests added: for each site, force the underlying call to throw and assert the warn-log was emitted with the expected fields. Use the existing logger-spy pattern from orchestrator.test.ts.
  • No regression in scan-error counting: each warn'd error increments the scan's error counter as today.

Files affected (likely)

  • packages/engine/src/scan/metadata-image.ts:59-61
  • packages/engine/src/scan/metadata-video.ts:33-35, 55-58
  • packages/engine/src/scan/walker.ts:56-60, 80-83, 137-141
  • Matching test files for each
  • Possibly packages/engine/src/log.ts — if the Logger doesn't already accept structured fields

Suggested approach

Thread a log?: Logger parameter through extractImageMetadata / extractVideoMetadata (currently they don't accept one) so the orchestrator passes its scoped logger in. For walker.ts, the walker already accepts options; add log?: Logger similarly.

Out of scope

  • Hard-aborting on permission errors (deliberate non-goal per spec §5.6 "File-level errors: logged, file skipped, scan continues").
  • Surfacing the warnings into the UI (a future "scan-error log viewer" feature; current logs are file-only per spec §12.4).

References

  • Standards: coding-standards.md — "Silent catches"
  • Spec §5.6 — "File-level errors: logged, file skipped, scan continues"
  • Code: packages/engine/src/scan/metadata-image.ts:59-61, metadata-video.ts:33-35, 55-58, walker.ts:56-60, 80-83, 137-141

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions