Skip to content

fix(auth): enrich API error cause + retry the user-data fetch#908

Draft
posthog[bot] wants to merge 1 commit into
mainfrom
posthog-code/enrich-auth-fetch-errors
Draft

fix(auth): enrich API error cause + retry the user-data fetch#908
posthog[bot] wants to merge 1 commit into
mainfrom
posthog-code/enrich-auth-fetch-errors

Conversation

@posthog

@posthog posthog Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Problem

The wizard's login step threw a generic ApiError: Failed to fetch user data for any non-4xx failure hitting GET /api/users/@me/ during auth. Every network error, timeout, and 5xx collapsed into one opaque message — the captured $exception carried no status code or underlying cause, and endpoint was landing as None. That left a blind spot: transient infra blips were indistinguishable from a genuine auth regression. Low volume and intermittent, but it mostly hurts the team building the wizard, since the OAuth login path lets the throw block setup while the CI path swallows it.

Changes

  • handleApiError now classifies failures with an ApiErrorKind discriminant (network / timeout / server / auth / forbidden / not_found / client / parse / unknown), keeps the originating error as cause, and folds the transport-level code (ECONNABORTED, ETIMEDOUT, ENOTFOUND, …) or HTTP status into the message instead of the bare Failed to … string.
  • ApiError gains isTransient and a toProperties() bag; fetchUserData/fetchProjectData spread that bag into the captured exception so endpoint, statusCode, error_kind, and cause actually land on the $exception.
  • fetchUserData retries transient failures with exponential backoff before surfacing a hard failure on the OAuth path; auth/permission/parse failures still fail fast. The exception is captured exactly once, after retries are exhausted.

Test plan

  • New src/lib/__tests__/api.test.ts covers each handleApiError classification and the retry loop (first-try success, transient-then-success with backoff, non-transient fail-fast, and retry exhaustion with enriched capture props).
  • pnpm build && pnpm test — 1339 tests pass. pnpm lint — 0 errors; src/lib/api.ts is warning-free.

LLM context

Authored by PostHog Code (Claude) from an inbox error-tracking report on the generic non-4xx fallback in handleApiError.


Created with PostHog Code from an inbox report.

The wizard's login step surfaced a generic `ApiError: Failed to fetch
user data` for every non-4xx failure, so network errors, timeouts, and
5xx all collapsed into one opaque message with no status or cause on the
captured `$exception`.

`handleApiError` now classifies failures with an `ApiErrorKind`
discriminant (network / timeout / server / auth / forbidden / not_found /
client / parse / unknown), keeps the underlying error as `cause`, and
puts the transport-level code or status into the message. `ApiError`
exposes `isTransient` and a `toProperties()` bag so the endpoint, status,
kind, and cause actually land on the analytics exception.

`fetchUserData` now retries transient failures (network / timeout / 5xx)
with exponential backoff before surfacing a hard error on the OAuth login
path; auth/permission/parse failures still fail fast. The exception is
captured exactly once, after retries are exhausted.

Generated-By: PostHog Code
Task-Id: c6122001-868a-43f1-9059-050712a4b89e
@github-actions

Copy link
Copy Markdown

🧙 Wizard CI

Run the Wizard CI and test your changes against wizard-workbench example apps by replying with a GitHub comment using one of the following commands:

Test all apps:

  • /wizard-ci all

Test all apps in a directory:

  • /wizard-ci basic-integration
  • /wizard-ci mcp-analytics
  • /wizard-ci revenue

Test an individual app:

  • /wizard-ci basic-integration/android
  • /wizard-ci basic-integration/angular
  • /wizard-ci basic-integration/astro
Show more apps
  • /wizard-ci basic-integration/django
  • /wizard-ci basic-integration/fastapi
  • /wizard-ci basic-integration/flask
  • /wizard-ci basic-integration/javascript-node
  • /wizard-ci basic-integration/javascript-web
  • /wizard-ci basic-integration/laravel
  • /wizard-ci basic-integration/next-js
  • /wizard-ci basic-integration/nuxt
  • /wizard-ci basic-integration/python
  • /wizard-ci basic-integration/rails
  • /wizard-ci basic-integration/react-native
  • /wizard-ci basic-integration/react-router
  • /wizard-ci basic-integration/sveltekit
  • /wizard-ci basic-integration/swift
  • /wizard-ci basic-integration/tanstack-router
  • /wizard-ci basic-integration/tanstack-start
  • /wizard-ci basic-integration/vue
  • /wizard-ci mcp-analytics/custom-dispatcher
  • /wizard-ci mcp-analytics/typescript-sdk
  • /wizard-ci revenue/stripe

Results will be posted here when complete.

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