Skip to content

hubErrorHandler: report unhandled route errors through reportError - #440

Merged
TheGreatAxios merged 2 commits into
mainfrom
cl-7132-hubs-global-onerror-handler-never-calls-reporterror
Aug 29, 2026
Merged

TheGreatAxios merged 2 commits into
mainfrom
cl-7132-hubs-global-onerror-handler-never-calls-reporterror

Conversation

@TheGreatAxios

@TheGreatAxios TheGreatAxios commented Aug 28, 2026 •

Copy link
Copy Markdown
Contributor

Fixes CL-7132 — https://linear.app/abklabs/issue/CL-7132

Problem

hubErrorHandler (apps/hub/src/hub-error-handler.ts), wired via app.onError(...) in apps/hub/src/index.ts:1104, is documented as "the one place every such exception is guaranteed to be logged" but only called log.error and returned a 500/422 body. reportError from @corbits/error-sink — which attaches operation/tenant context, redacts, and mints a refId a person can quote to support — was never called, so an unhandled route error reached the user with nothing to reference back.

Change

  • hubErrorHandler now calls reportError(err, { operation: "hub.unhandled_route_error", tenantId?, extra: { path, method } }) and includes the returned refId in both the generic 500 body and the guidance-error 422 body (existing shape kept, refId field added).
  • tenantId is read via Context<TenantEnv> (the same TenantEnv from @intx/hub-api that packages/access-policy/src/routes.ts and others already type c.get("tenant") with) — c.var.tenant?.id when a tenant-scoped route set it. The handler also serves non-tenant routes, so this stays optional rather than assuming the wider type.
  • Dropped the old log.error tagged-template call — reportError already logs the same information (message, path, method) through @intx/log's ["errors"] category, so keeping both would be double-logging. hubErrorHandler no longer takes a log parameter; the app.onError call site was updated accordingly.
  • No change to user-facing message copy.

Tests

Extended apps/hub/src/hub-error-handler.test.ts to capture the ["errors"] LogTape category the way packages/error-sink/src/index.test.ts captures its own sink, and assert:

  • the JSON error body carries a non-empty refId for both the generic-500 and guidance-422 paths,
  • the captured log record's operation is "hub.unhandled_route_error" and its refId/extra.path/extra.method match.

Commit structure

This ships as a single commit rather than tests-first-then-implementation: the test asserts on the new zero-arg hubErrorHandler() signature, which only exists once the log parameter is dropped, so a tests-only commit wouldn't compile on its own. Every commit in the branch needs to pass the gate, so the two changes are squashed together instead.

Ran focused gates (package load average was too high for the full bun run check at commit time): bun test apps/hub/src/hub-error-handler.test.ts, bunx tsc --noEmit -p apps/hub, bunx prettier --write + bunx eslint on changed files, and bun run check:no-product-tenancy. CI runs the full gate.

@TheGreatAxios
TheGreatAxios force-pushed the cl-7132-hubs-global-onerror-handler-never-calls-reporterror branch from 02ca1eb to 5cfad18 Compare August 28, 2026 12:47
The global onError handler only called log.error and returned a 500/422
body, so an unhandled route exception left no refId a user could quote
back to support. It now reports through @corbits/error-sink's
reportError (operation, tenantId when a tenant-scoped route set one via
the same TenantEnv other routes use, and path/method as extra) and
includes the returned refId in both the generic 500 body and the
guidance-error 422 body. The old log.error tagged-template call is
dropped in favor of reportError's own logging, so the handler no longer
takes a log parameter.

Fixes CL-7132.
@TheGreatAxios
TheGreatAxios force-pushed the cl-7132-hubs-global-onerror-handler-never-calls-reporterror branch from 5cfad18 to 1e50889 Compare August 29, 2026 04:46

@TheGreatAxios TheGreatAxios left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critique · comment

hubErrorHandler reports through reportError and returns { error, refId }.

  • apps/hub/src/error-handler.ts:17-27 — tenantId is on the options type and in the reportError payload, but no test asserts it is forwarded. The handler does pass options.tenantId when present; the gap is the missing assertion.

Walking-skeleton red on this PR is main deleting DATABASE_URL after memory-mount tests (CL-7182 / #465), not this diff.

@TheGreatAxios
TheGreatAxios merged commit 0cf8feb into main Aug 29, 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