Route onboarding's caught errors through reportError - #509
Merged
TheGreatAxios merged 2 commits intoAug 30, 2026
Merged
TheGreatAxios merged 2 commits into
TheGreatAxios merged 2 commits into
Conversation
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
CL-7234:
packages/onboarding'sroutes.ts,bench-provisioning.ts, andplant-env-credentials.tsonly logged a caught failure and never reached@corbits/error-sink'sreportError, inconsistent with this same package's ownprovision.tsprecedent (reportError(cause, { operation: "reconcile_seed_grants", tenantId: own.tenantId })).Seven sites fixed:
routes.ts'sreportOnboardingError(the single funnel all 5 route catches go through:/provisionx2,/complete,/complete-setup,/provisioning-status) now also callsreportError, reusing the samerefIdit already generates for the client-facing envelope.operationis 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 (aProvisionError's own.codecan be things likeslug_conflict_no_principal); that code goes intoextrainstead.tenantIdis threaded through wherever a route already resolves one before it can fail (/complete,/complete-setup,/provisioning-statuseach hoist alet tenantIdand assign it right after the relevant lookup succeeds);/provisiongenuinely has none yet (a brand-new signup has no tenant, andProvisionErrorcarries no tenantId field).bench-provisioning.ts'swake()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 existingholdOff) — now reports withoperation: "bench_provisioning_drain"and no tenant/user, since none exists at that scope.plant-env-credentials.ts's tworunSeedCatalogcatches now report withtenantId+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'smessagenow passes throughsanitizeProviderMessagefirst — the same redaction the pre-existing probe-failure path a few lines below already applied — instead of logging an unredacted copy sitting right next toreportError's own redacted one.On the
report-error-ignore: CL-7234opt-out commentsPR #497 (CL-7237,
check:report-error) is unmerged as of this PR and adds 5report-error-ignore: CL-7234opt-out comments at these exact sites, against a shrink-only baseline. This branch is stacked offcl-7233-evict-onboarding-maps, which is offorigin/main— not off #497's branch — so none of those comments exist in this tree; verified by diffingorigin/mainagainst #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-7234comments 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:
@workbench/hub-clientand@corbits/error-sinkeach carry an identicalgenerateRefIdimplementation; harmless today but a duplicated primitive error-sink should own alone.routes.ts'srecentlyConnectedCredential(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 passbunx prettier --checkon all touched filesbun run lint(root) — 0 errorsoperationnaming and pushed fortenantIdhoisting where cheaply available); Critique-reviewed the commits, clean — all 7 named sites confirmed reachingreportError, tenantId hoisting confirmed request-scoped (no staleness), bothplant-env-credentials.tsleaks confirmed fixed, test isolation confirmed independently (full suite passes forward and reversed file order)plant-env-credentials.ts's own catches never log or return an unredacted secretStacking
PR 2 of 2. Branches off
cl-7233-evict-onboarding-maps(#506) — do not merge before #506, and do not merge this one either.