hubErrorHandler: report unhandled route errors through reportError - #440
Merged
TheGreatAxios merged 2 commits intoAug 29, 2026
Merged
TheGreatAxios merged 2 commits into
TheGreatAxios merged 2 commits into
Conversation
TheGreatAxios
force-pushed
the
cl-7132-hubs-global-onerror-handler-never-calls-reporterror
branch
from
August 28, 2026 12:47
02ca1eb to
5cfad18
Compare
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
force-pushed
the
cl-7132-hubs-global-onerror-handler-never-calls-reporterror
branch
from
August 29, 2026 04:46
5cfad18 to
1e50889
Compare
TheGreatAxios
commented
Aug 29, 2026
TheGreatAxios
left a comment
Contributor
Author
There was a problem hiding this comment.
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.
…nerror-handler-never-calls-reporterror
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.
Fixes CL-7132 — https://linear.app/abklabs/issue/CL-7132
Problem
hubErrorHandler(apps/hub/src/hub-error-handler.ts), wired viaapp.onError(...)inapps/hub/src/index.ts:1104, is documented as "the one place every such exception is guaranteed to be logged" but only calledlog.errorand returned a 500/422 body.reportErrorfrom@corbits/error-sink— which attaches operation/tenant context, redacts, and mints arefIda person can quote to support — was never called, so an unhandled route error reached the user with nothing to reference back.Change
hubErrorHandlernow callsreportError(err, { operation: "hub.unhandled_route_error", tenantId?, extra: { path, method } })and includes the returnedrefIdin both the generic 500 body and the guidance-error 422 body (existing shape kept,refIdfield added).tenantIdis read viaContext<TenantEnv>(the sameTenantEnvfrom@intx/hub-apithatpackages/access-policy/src/routes.tsand others already typec.get("tenant")with) —c.var.tenant?.idwhen a tenant-scoped route set it. The handler also serves non-tenant routes, so this stays optional rather than assuming the wider type.log.errortagged-template call —reportErroralready logs the same information (message, path, method) through@intx/log's["errors"]category, so keeping both would be double-logging.hubErrorHandlerno longer takes alogparameter; theapp.onErrorcall site was updated accordingly.Tests
Extended
apps/hub/src/hub-error-handler.test.tsto capture the["errors"]LogTape category the waypackages/error-sink/src/index.test.tscaptures its own sink, and assert:refIdfor both the generic-500 and guidance-422 paths,operationis"hub.unhandled_route_error"and itsrefId/extra.path/extra.methodmatch.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 thelogparameter 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 checkat commit time):bun test apps/hub/src/hub-error-handler.test.ts,bunx tsc --noEmit -p apps/hub,bunx prettier --write+bunx eslinton changed files, andbun run check:no-product-tenancy. CI runs the full gate.