Commit Graph
2 Commits
Author SHA1 Message Date
ZacharyZhang-NY 827f06f358 Migrate 26 high-value catch sites to AppError taxonomy (C6 wave 1)
Classify scheduler, orchestration, IPC read, and automation catch
blocks via logAppError + classifyUnknownError so each failure surfaces
a stable `module.subdomain.condition` code plus a kind. No behaviour
change — returns, throws, and fall-through are preserved; only log
prefixes and the taxonomy metadata are new.

Wave 1 coverage (26 sites, all non-database):

  - orchestration/scheduler-lock-recovery (3)
  - orchestration/scheduler-housekeeping (5)
  - orchestration/scheduler-idle-automation (2)
  - orchestration/scheduler-heartbeat (4)
  - orchestration/turn-context (2)
  - ipc-core-read-handlers (6)
  - automation/automation-handlers (4)

Relax the Logger interface so `error` is optional, letting callers
whose deps expose only `{info, warn}` (scheduler contexts) pass in
directly without wrapping. The helper falls back to warn when error
is absent.
2026-04-20 13:37:40 -04:00
ZacharyZhang-NY 08427931b6 Introduce AppError taxonomy with 4 kinds (C6.1 part 1/2)
Establishes `src/main/errors/` with:

- `AppError` base + `Recoverable|UserInput|Upstream|Fatal` subclasses
  keyed on a narrow `ErrorKind = "recoverable" | "user_input" |
  "upstream" | "fatal"` union. Four kinds is deliberate: adding a fifth
  is a conscious proposal, not an inline decision at a catch site.
- `classifyUnknownError(e, fallback)` — required-fallback-meta wrapper
  that refuses to invent classification. If `e` is already an
  AppError it is returned untouched; otherwise the call site's
  intent wins and the raw value is preserved via `cause` (for Error
  instances) or `context.raw` (for anything else).
- `logAppError(logger, raw, fallback, level?)` helper emits one
  structured log line and returns the classified AppError so the
  caller can still branch on `err.kind`.

Why this module exists: 248 catch blocks in src/main/ today are
overwhelmingly `} catch {}` or `log.warn(); return default`. Behaviour
is correct case-by-case but the codebase has no machine-readable signal
for "is this recoverable vs fatal", making it impossible to write
graceful-shutdown logic, telemetry buckets, or catch-site audits.

Part 2 migrates the top-20 high-frequency catch sites. Part 3 (tracked
as C6.2 proposal) covers the remaining 228.

No behavioural change in this commit — it only adds the classifier and
exports.
2026-04-20 12:14:55 -04:00