Two related problems with how we report errors to Sentry.
First, three database failures in the client-auth path get logged with console.error and then forgotten. They never reach Sentry, so we're blind to them in production.
Second, the Elysia onError hook sends every error to Sentry, including routine 4xx like favicon bots hitting NOT_FOUND. That noise buries the errors we actually care about.
They sit in overlapping code, so it's easier to fix them together.
1. Capture the three swallowed DB errors. Each one currently console.errors and moves on:
platform/src/server.ts:48 — migration run failure (runMigrations()).
platform/src/auth/instance-auth.ts:139 — startup DB-probe (reachability) failure; auth degrades to the shape-checked forward path.
platform/src/auth/instance-auth.ts:275 — runtime client-lookup failure; request fails closed.
Each of these needs an explicit captureException(err, …) next to the log it already writes. captureException is already imported in instance-auth.ts:7 and used elsewhere in that file (lines 158, 251, 312), so those two sites are just inconsistent with the rest of it. server.ts needs the import adding (import { captureException } from "./util/sentry").
2. Skip 4xx in the onError hook. Request errors only reach Sentry through the onError hook at platform/src/server.ts:30-32, and it calls captureException(error) for everything. Add a status check so we only capture 5xx and unexpected errors, and skip the routine 4xx like NOT_FOUND. Elysia hands us the error code and status on the onError context, so the guard lives right there in the hook.
Sentry is wired in platform/src/util/sentry.ts (captureException is a no-op when SENTRY_DSN is unset) and initialised from platform/src/index.ts:4.
Acceptance criteria
Two related problems with how we report errors to Sentry.
First, three database failures in the client-auth path get logged with
console.errorand then forgotten. They never reach Sentry, so we're blind to them in production.Second, the Elysia
onErrorhook sends every error to Sentry, including routine 4xx like favicon bots hittingNOT_FOUND. That noise buries the errors we actually care about.They sit in overlapping code, so it's easier to fix them together.
1. Capture the three swallowed DB errors. Each one currently
console.errors and moves on:platform/src/server.ts:48— migration run failure (runMigrations()).platform/src/auth/instance-auth.ts:139— startup DB-probe (reachability) failure; auth degrades to the shape-checked forward path.platform/src/auth/instance-auth.ts:275— runtime client-lookup failure; request fails closed.Each of these needs an explicit
captureException(err, …)next to the log it already writes.captureExceptionis already imported ininstance-auth.ts:7and used elsewhere in that file (lines 158, 251, 312), so those two sites are just inconsistent with the rest of it.server.tsneeds the import adding (import { captureException } from "./util/sentry").2. Skip 4xx in the
onErrorhook. Request errors only reach Sentry through theonErrorhook atplatform/src/server.ts:30-32, and it callscaptureException(error)for everything. Add a status check so we only capture 5xx and unexpected errors, and skip the routine 4xx likeNOT_FOUND. Elysia hands us the error code and status on theonErrorcontext, so the guard lives right there in the hook.Sentry is wired in
platform/src/util/sentry.ts(captureExceptionis a no-op whenSENTRY_DSNis unset) and initialised fromplatform/src/index.ts:4.Acceptance criteria
platform/src/server.ts:48callscaptureException, with the import added toserver.ts.platform/src/auth/instance-auth.ts:139callscaptureException.platform/src/auth/instance-auth.ts:275callscaptureException.onErrorhook (platform/src/server.ts:30-32) only captures 5xx/unexpected errors; 4xx (e.g.NOT_FOUND) is skipped.onErrorstill returns nothing so Elysia produces its normal error body/status.