Repository navigation
feat: report errors to self-hosted GlitchTip - #94
Conversation
Adds the Sentry SDK pointed at the self-hosted GlitchTip instance at errors.ericdahl.dev, covering client, server and edge runtimes. Server errors had no reporting at all before this; PostHog only captured client exceptions. Shared options live in app/lib/observability/sentry-options.ts so the behaviour is testable: disabled without a DSN (and always disabled under test), client reads only NEXT_PUBLIC_SENTRY_DSN so no server-only DSN can reach the bundle, and release comes from Coolify's SOURCE_COMMIT. SDK v11 collects cookies, HTTP headers and query params by default. This app carries Neon Auth session cookies and node auth tokens, so every dataCollection category is turned off explicitly. Replay and tracing are pinned off: GlitchTip implements neither fully. Source map upload is disabled until an upload step and auth token exist. PostHog is left untouched, including capture_exceptions.
Strix Security ReviewNo security issues found. Review summaryReviewed all changed files in this PR (the Sentry/GlitchTip wiring for client, server, and edge runtimes, the shared options module, Next.js config, dependency addition, and the unit tests; the yarn.lock diff is a lock file and was not treated as security-relevant). The review focused on the two sensitive-data risk areas this change introduces: what error payloads the SDK could transmit to the self-hosted GlitchTip instance, and whether any server-only configuration could leak into the browser bundle. The data-collection controls were verified against the resolved @sentry/nextjs v11.0.0 Updated for Reviewed by Strix |
PR #94 read the DSN through a helper that indexes process.env dynamically. Next only substitutes literal `process.env.NEXT_PUBLIC_*` expressions when building the client bundle, so the dynamic read survived into the browser as undefined and Sentry disabled itself with no error. Verified against the deployed site: the SDK shipped but the DSN string was absent, while PostHog's token was inlined because it is referenced literally. Server and edge runtimes were unaffected — they read process.env at runtime. The client now passes literal references explicitly, and a guard test asserts the literal is present and that the no-argument form is not used, since a unit test cannot observe bundler substitution. Confirmed with a real build: a probe DSN now appears in a client chunk.
Wires the Sentry SDK to the self-hosted GlitchTip instance at
errors.ericdahl.dev, covering the client, server and edge runtimes.Before this, server-side errors were reported nowhere. PostHog's
capture_exceptionsonly covers the browser, so anything thrown in a route handler, server component orproxy.tswas invisible.Approach
Shared options live in
app/lib/observability/sentry-options.tsrather than being repeated across four init calls, which makes the behaviour testable without testingSentry.inititself. 11 unit tests cover:NODE_ENV=test, so local dev and CI never ship events.NEXT_PUBLIC_SENTRY_DSN, so a server-onlySENTRY_DSNcan never be inlined into the browser bundle.releasecomes from Coolify'sSOURCE_COMMIT, overridable viaSENTRY_RELEASE.Security note for review
SDK v11 changed the defaults here:
dataCollection.cookies,httpHeaders,urlQueryParamsandhttpBodiesall default to collected. This app carries Neon Auth session cookies and node auth tokens, so every category is turned off explicitly. This is the v11 replacement for the oldsendDefaultPii: false, which no longer exists in the options type.NEXT_PUBLIC_SENTRY_DSNis present in the client bundle by design — a DSN is a public, write-only ingest key, not a secret. It is not a credential leak.Deliberately out of scope
relay.tsis not instrumented. It runs on users' own machines, so reporting their process errors into our GlitchTip would be a privacy problem.capture_exceptions. Errors will land in both places for now; that is intentional so there is nothing to undo if GlitchTip disappoints.server.ts/app/lib/ws/node-socket.ts) sits outside Next's request lifecycle, soonRequestErrordoes not see it. Uncaught errors there are still caught by the SDK's global handlers, but anything caught-and-logged needs an explicitcaptureExceptionto be reported.chunk-uploadendpoint advertisesrelease_filesandartifact_bundles, so the bundler plugin's upload path should work once an auth token and CI step exist. Follow-up, not this PR.Deploy steps (after merge)
NEXT_PUBLIC_SENTRY_DSNmust be added to the Coolify app as both build-time and runtime (matching howNEXT_PUBLIC_POSTHOG_PROJECT_TOKENis set) or it will beundefinedin the bundle. Value is in Doppler asCLAWPROXY_GLITCHTIP_DSN.Verification
yarn lintcleanyarn test:run— 302 tests, 69 files, all passingyarn buildpasses with turbopackNote
withSentryConfigmoved to@sentry/nextjs/configin v11; importing it from the package root fails at build time.