fix(backend): attach Postgres cause and SQLSTATE to captured exceptions - #3299
fix(backend): attach Postgres cause and SQLSTATE to captured exceptions#3299posthog-eu[bot] wants to merge 1 commit into
Conversation
capturePosthogException only shipped the Drizzle message to error tracking: the SQL text plus the bound query values, with no SQLSTATE and no cause. That made DrizzleQueryError issues undiagnosable and leaked bound values (org UUIDs) into the exception value. Resolve the underlying database error from either a raw Drizzle error (.cause) or a quickError()-wrapped HTTP error (.cause.originalCause), then attach pg_error_code and a param-free database_cause, and strip the trailing `params:` line from the exception value. This is the single shared capture path, so every route that maps a query failure to quickError(..., cause) now reports the same detail. Generated-By: PostHog Desktop Task-Id: c051ced0-6a49-4e7e-a634-e6c5f705d28d
|
Important Review skippedBot user detected. To trigger a single review, invoke the ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Merging this PR will not alter performance
Comparing Footnotes
|
|



Summary
capturePosthogExceptionshipped only the Drizzle message (the SQL text plus the bound query values) to error tracking. No SQLSTATE, no cause. The same blind spot already stalled a separate, noisier Drizzle error class..cause) or aquickError()-wrapped HTTP error (.cause.originalCause), then attachpg_error_codeand a param-freedatabase_cause, and strip the trailingparams:line from the exception value.quickError(..., cause)(not just this one) now reports the SQLSTATE and Postgres reason.$exception.valueFailed query: ... \nparams: <org-uuid>Failed query: ...(params dropped)pg_error_codekind: drizzle_errordatabase_cause{ name, message }of the real Postgres errorTest plan
bunx vitest run tests/posthog.unit.test.ts— two new cases: a raw Drizzle error (params stripped, SQLSTATE + cause kept) and aquickError-wrapped HTTP exception (cause surfaced fromoriginalCause).bun run typecheck:backendandbun run lint:ox:backendpass.Screenshots
Checklist
bun run lint:backend && bun run lint.accordingly.
my tests
Agent context
The originating report also proposed wrapping the
readOrgNotificationOverviewcall inquickError(503, ..., error)so transient replica failures stop paging. I dropped that half after checkingon_error.ts: since a483655 (2026-08-26, before the reported occurrence) it already converts a transient DB failure thrown from any handler into a 503upstream_unavailablewith no page. Wrapping this call would add no transient coverage and would mislabel a genuine (non-transient) SQL bug as a retry-able 503 while dropping thedrizzle_errorstructured cloudlog. The sibling wrap a few lines below is still correct because it guards a Cloudflare analytics call, whose failures are not DB-origin and so are not classified byon_error.Created with PostHog Desktop from this inbox report.
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.