Skip to content

fix(backend): attach Postgres cause and SQLSTATE to captured exceptions - #3299

Draft
posthog-eu[bot] wants to merge 1 commit into
mainfrom
posthog-self-driving/fixapi-attach-postgres-cause-to-org-85e5dd
Draft

fix(backend): attach Postgres cause and SQLSTATE to captured exceptions#3299
posthog-eu[bot] wants to merge 1 commit into
mainfrom
posthog-self-driving/fixapi-attach-postgres-cause-to-org-85e5dd

Conversation

@posthog-eu

@posthog-eu posthog-eu Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Problem: a Postgres failure behind the org notification overview returned a 500 and paged Discord, but the issue was undiagnosable — capturePosthogException shipped 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.
  • Fix (mechanism): 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.
  • Blast radius: the change lives in the single shared capture path, so every route that maps a query failure to quickError(..., cause) (not just this one) now reports the SQLSTATE and Postgres reason.
  • Privacy: the bound query values (org UUIDs and other request data) no longer ride along in the exception value.
Field Before After
$exception.value Failed query: ... \nparams: <org-uuid> Failed query: ... (params dropped)
pg_error_code only for kind: drizzle_error any DB-origin error, incl. wrapped HTTP exceptions
database_cause absent { name, message } of the real Postgres error

Test plan

  • bunx vitest run tests/posthog.unit.test.ts — two new cases: a raw Drizzle error (params stripped, SQLSTATE + cause kept) and a quickError-wrapped HTTP exception (cause surfaced from originalCause).
  • bun run typecheck:backend and bun run lint:ox:backend pass.

Screenshots

Checklist

  • My code follows the code style of this project and passes
    bun run lint:backend && bun run lint.
  • My change requires a change to the documentation.
  • I have updated the documentation
    accordingly.
  • My change has adequate E2E test coverage.
  • I have tested my code manually, and I have provided steps how to reproduce
    my tests

Agent context

The originating report also proposed wrapping the readOrgNotificationOverview call in quickError(503, ..., error) so transient replica failures stop paging. I dropped that half after checking on_error.ts: since a483655 (2026-08-26, before the reported occurrence) it already converts a transient DB failure thrown from any handler into a 503 upstream_unavailable with 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 the drizzle_error structured 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 by on_error.


Created with PostHog Desktop from this inbox report.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

Review in cubic

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
@coderabbitai

coderabbitai Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 68d0c028-385b-46e4-ab21-1baf4fa37923

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codspeed-hq

codspeed-hq Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 43 untouched benchmarks
⏩ 2 skipped benchmarks1


Comparing posthog-self-driving/fixapi-attach-postgres-cause-to-org-85e5dd (6ce7061) with main (387a845)

Open in CodSpeed

Footnotes

  1. 2 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@sonarqubecloud

Copy link
Copy Markdown

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.

0 participants