Skip to content

Route onboarding's caught errors through reportError - #509

Merged
TheGreatAxios merged 2 commits into
cl-7233-evict-onboarding-mapsfrom
cl-7234-onboarding-report-error
Aug 30, 2026
Merged

TheGreatAxios merged 2 commits into
cl-7233-evict-onboarding-mapsfrom
cl-7234-onboarding-report-error

Conversation

@TheGreatAxios

Copy link
Copy Markdown
Contributor

Summary

CL-7234: packages/onboarding's routes.ts, bench-provisioning.ts, and plant-env-credentials.ts only logged a caught failure and never reached @corbits/error-sink's reportError, inconsistent with this same package's own provision.ts precedent (reportError(cause, { operation: "reconcile_seed_grants", tenantId: own.tenantId })).

Seven sites fixed:

  • routes.ts's reportOnboardingError (the single funnel all 5 route catches go through: /provision x2, /complete, /complete-setup, /provisioning-status) now also calls reportError, reusing the same refId it already generates for the client-facing envelope. operation is a small, stable, snake_case action name per route (onboarding_provision, onboarding_complete, onboarding_complete_setup, onboarding_provisioning_status) — never the failure code itself, which is an unbounded per-error taxonomy (a ProvisionError's own .code can be things like slug_conflict_no_principal); that code goes into extra instead. tenantId is threaded through wherever a route already resolves one before it can fail (/complete, /complete-setup, /provisioning-status each hoist a let tenantId and assign it right after the relevant lookup succeeds); /provision genuinely has none yet (a brand-new signup has no tenant, and ProvisionError carries no tenantId field).
  • bench-provisioning.ts's wake() catch — a whole-drain failure (e.g. store.listDue() itself throwing), not scoped to any one bench (per-seed failures already carry tenant context via the existing holdOff) — now reports with operation: "bench_provisioning_drain" and no tenant/user, since none exists at that scope.
  • plant-env-credentials.ts's two runSeedCatalog catches now report with tenantId + provider. This module handles a live API key end-to-end, so while in there: the raw cause text that used to go straight into the log line and the returned outcome's message now passes through sanitizeProviderMessage first — the same redaction the pre-existing probe-failure path a few lines below already applied — instead of logging an unredacted copy sitting right next to reportError's own redacted one.

On the report-error-ignore: CL-7234 opt-out comments

PR #497 (CL-7237, check:report-error) is unmerged as of this PR and adds 5 report-error-ignore: CL-7234 opt-out comments at these exact sites, against a shrink-only baseline. This branch is stacked off cl-7233-evict-onboarding-maps, which is off origin/main — not off #497's branch — so none of those comments exist in this tree; verified by diffing origin/main against #497's branch directly. There is nothing to remove here.

Whoever merges second inherits the conflict: if #497 lands first, this PR's changes will need to drop the now-unnecessary report-error-ignore: CL-7234 comments as part of resolving/rebasing (the work they were opting out of is done). If this PR lands first, #497's baseline pass should simply not add opt-out comments for these 5 sites at all, since they'll already pass the check. Either way, please don't let an opt-out comment for already-completed work survive as dead weight — flagging explicitly since it's exactly the kind of thing that lingers forever otherwise.

Findings not fixed here (filed separately)

Greybeard and Critique review surfaced two more instances of the same underlying gaps, both correctly out of CL-7234's named scope:

  • CL-7253@workbench/hub-client and @corbits/error-sink each carry an identical generateRefId implementation; harmless today but a duplicated primitive error-sink should own alone.
  • CL-7255routes.ts's recentlyConnectedCredential (a best-effort duplicate-callback recovery check, never client-facing) has its own catch that still only logs, not one of CL-7234's named 7 sites but the same defect class.

Test plan

  • cd packages/onboarding && bun run typecheck && bun test — 169 pass
  • bunx prettier --check on all touched files
  • bun run lint (root) — 0 errors
  • Greybeard-reviewed design (corrected operation naming and pushed for tenantId hoisting where cheaply available); Critique-reviewed the commits, clean — all 7 named sites confirmed reaching reportError, tenantId hoisting confirmed request-scoped (no staleness), both plant-env-credentials.ts leaks confirmed fixed, test isolation confirmed independently (full suite passes forward and reversed file order)
  • No real credentials in tests; plant-env-credentials.ts's own catches never log or return an unredacted secret

Stacking

PR 2 of 2. Branches off cl-7233-evict-onboarding-maps (#506) — do not merge before #506, and do not merge this one either.

routes.ts, bench-provisioning.ts, and plant-env-credentials.ts only
logged a caught failure; provision.ts already routes through
@corbits/error-sink's reportError for the operation/tenant context, a
refId, and secret redaction (CL-7234). Asserts on the reportError call
itself (operation, tenantId, extra) rather than only observable
response shape, and proves the two plant-env-credentials.ts catches
stop leaking a raw cause message once they're fixed.
routes.ts, bench-provisioning.ts, and plant-env-credentials.ts only
logged a caught failure and never reached @corbits/error-sink,
inconsistent with this same package's own provision.ts (CL-7234).

- routes.ts's reportOnboardingError funnel (every route catch) now
  also calls reportError, with a snake_case operation per route action
  (never the failure code itself, which is an unbounded per-error
  taxonomy) plus tenantId wherever a route already resolves one before
  it can fail, and userId in extra everywhere.
- bench-provisioning.ts's drain-level catch (a whole-tick failure, not
  scoped to any one bench — per-seed failures already carry tenant
  context via holdOff) now reports with no tenant/user, since none
  exists at that scope.
- plant-env-credentials.ts's two seedCatalog-throw catches now report
  with tenantId + provider, and — this module handles a live API key —
  the raw cause text logged and returned in PlantEnvProviderCredentialsOutcome
  now goes through the same sanitizeProviderMessage redaction the
  probe-failure path already applied, instead of logging the
  unredacted message next to a safe copy.
@TheGreatAxios
TheGreatAxios merged commit 198cbaf into cl-7233-evict-onboarding-maps Aug 30, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant