Skip to content

fix(data-imports): keep exhausted Notion 5xx retries out of error tracking - #73485

Merged
Gilbert09 merged 2 commits into
masterfrom
posthog-code/fix-notion-5xx-retryable-error-tracking-noise
Jul 24, 2026
Merged

fix(data-imports): keep exhausted Notion 5xx retries out of error tracking#73485
Gilbert09 merged 2 commits into
masterfrom
posthog-code/fix-notion-5xx-retryable-error-tracking-noise

Conversation

@Gilbert09

Copy link
Copy Markdown
Member

Problem

Error tracking caught a NotionRetryableError (Notion API error (retryable): status=522, url=https://api.notion.com/v1/comments) in the data-warehouse import pipeline (issue).

The stack trace confirms it originates in notion.py's _request (line 188), reached via the comments fan-out stream (_comments_streamget_rows → the shared import pipeline).

_request already retries a 5xx internally with exponential backoff via tenacity (5 attempts) before giving up and re-raising NotionRetryableError. When those internal retries are exhausted, the exception falls through to _handle_import_error's default branch, which logs it with logger.aexception(...) — capturing it as a tracked exception — before re-raising so Temporal retries the whole activity.

A 522 (origin timed out, per Cloudflare's status code in front of Notion's API) is a transient infrastructure condition, not something PostHog's code or the customer's config can fix. Since Temporal already retries the activity and the failure is self-recovering, this doesn't need to reach error tracking as noise.

Decision

Classified as a fixable improvement, not a user/upstream error: the source already has a mechanism for exactly this (get_retryable_errors() on ResumableSource, used to keep self-recovering, internally-retried failures out of error tracking), but NotionSource didn't implement it. Mixpanel, Intercom, and MongoDB sources already use this same mechanism for their own transient/self-recovering errors, so this follows established precedent rather than introducing a new pattern.

Changes

  • Added get_retryable_errors() to NotionSource, matching the stable "Notion API error (retryable)" prefix that _request raises on any 5xx.

How did you test this code?

Added test_retryable_marker_matches_raised_message to test_notion_source.py, mirroring the equivalent Mixpanel test — asserts the marker returned by get_retryable_errors() matches the exact message _request raises on a 5xx. This is the regression: without the fix, an exhausted-retry 5xx would keep being logged as a tracked exception.

Ran:

  • uv run pytest products/warehouse_sources/backend/temporal/data_imports/sources/notion/tests/test_notion_source.py — 22 passed
  • ruff check --fix / ruff format on both changed files — clean
  • uv run mypy --cache-fine-grained . (repo-wide) — clean, no issues in 16783 source files

Automatic notifications

  • Publish to changelog?
  • Alert Sales and Marketing teams?

Docs update

N/A — internal error-classification change, no user-facing behavior change.

🤖 Agent context

Autonomy: Fully autonomous

Triaged a webhook-delivered error tracking issue using the PostHog MCP error-tracking tools (query-error-tracking-issue, query-error-tracking-issue-events) to pull the full stack trace and confirm the failure genuinely originates in the Notion source's _request. Read notion.py and source.py to understand the retry/classification flow, and found the get_retryable_errors() precedent already used by the Mixpanel, Intercom, and MongoDB sources for the same class of problem (self-recovering errors already retried internally). Invoked /writing-tests before adding the regression test. Checked for duplicate open PRs by exception type, message phrase, and module path, and reviewed the maintainer's own open PR queue — found one Notion-related draft (#71645) but it addresses 401/403 auth-expiry classification, an unrelated code path.

…cking

Notion's `_request` already retries a 5xx internally with backoff (tenacity) before re-raising `NotionRetryableError`. When those retries exhaust, the error was falling through to `_handle_import_error`'s default branch, which logs it as a tracked exception even though Temporal will retry the whole activity and the failure is self-recovering.

Add `get_retryable_errors()` to `NotionSource`, matching the stable "Notion API error (retryable)" prefix, so this classifies the same way it already does for Mixpanel/Intercom/MongoDB sources.

Generated-By: PostHog Code
Task-Id: 180d4aa8-841d-4c96-a131-4099938361fc
@github-actions

Copy link
Copy Markdown
Contributor

Hey @Gilbert09! 👋

It looks like your git author email on this PR isn't your @posthog.com address (owerstom@gmail.com). Since you're on the PostHog team, it's worth pointing your local git author email at your @posthog.com address. Why it matters:

  • Consistent work identity in git history — internal tooling that attributes commits to team members keys off your @posthog.com address.
  • Keeps team contributions easy to tell apart from external community ones when scanning history.

You can fix it for this repo with:

git config user.email "you@posthog.com"

Or set it globally with git config --global user.email "you@posthog.com". No need to redo this PR — just a nudge for next time. 🙂

@pr-assigner-resolver-posthog
pr-assigner-resolver-posthog Bot requested a review from a team July 24, 2026 11:11
@github-actions

github-actions Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

🦔 Hogbox preview · ✅ ready

▶ Open the preview

🔑 Login test@posthog.com / 12345678 (demo data)
🧩 Running this PR's backend and frontend, on the PostHog :master base
🔗 Link stable across rebuilds — a re-push swaps the box underneath, the URL stays
🔒 Access tailnet only (PostHog VPN)
🛠️ Admin inspect & debug state in hogland
💤 Idle sleeps after ~30 min idle (snapshot to S3, zero node cost) and wakes on your next visit in ~30s, behind a brief "waking up" screen

commit 5d915b1 · box box-49c30b74ccb7 · ready in 997s (push → usable) · build log · rebuilds on every push, torn down on close

@github-actions

github-actions Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

🤖 CI report

Bundle size — no change

Uncompressed size of every built .js bundle, compared against the base branch.

Total: 64.39 MiB · no change

No file changed by more than 1000 B.

Posted automatically by build-bundle-size-report · uncompressed bytes from dist-report

Eager graph — within budget

How much code each root ships on the eager path — downloaded and parsed before the surface is interactive. Measured from the esbuild output chunks (post-tree-shake, static imports only); lazy import() / React.lazy chunks are not counted.

Root Eager (shipped) Δ vs base Budget
entry (logged-out pages, app bootstrap)
src/index.tsx
1.24 MiB · 22 files no change ███░░░░░░░ 27.5% of 4.51 MiB
authenticated shell (every logged-in page)
src/scenes/AuthenticatedShell.tsx
8.07 MiB · 3,010 files no change ████████░░ 83.1% of 9.71 MiB

🟢 node_modules/monaco-editor/ stays out of src/index.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/index.tsx
🟢 [object Object] stays out of src/index.tsx
🟢 [object Object] stays out of src/index.tsx
🟢 node_modules/monaco-editor/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/scenes/AuthenticatedShell.tsx
🟢 [object Object] stays out of src/scenes/AuthenticatedShell.tsx
🟢 [object Object] stays out of src/scenes/AuthenticatedShell.tsx

Largest files eagerly shipped from src/index.tsx
Size File
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
24.6 KiB ../node_modules/.pnpm/buffer@6.0.3/node_modules/buffer/index.js
6.3 KiB ../node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react.production.min.js
4.5 KiB ../node_modules/.pnpm/@jspm+core@2.1.0/node_modules/@jspm/core/nodelibs/browser/process.js
3.9 KiB ../node_modules/.pnpm/scheduler@0.23.2/node_modules/scheduler/cjs/scheduler.production.min.js
1.4 KiB ../node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js
1.3 KiB src/RootErrorBoundary.tsx
912 B ../node_modules/.pnpm/ieee754@1.2.1/node_modules/ieee754/index.js
789 B src/scenes/ChunkLoadErrorBoundary.tsx
762 B src/index.tsx
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx
Size File
281.5 KiB ../node_modules/.pnpm/posthog-js@1.407.2/node_modules/posthog-js/dist/rrweb.js
267.7 KiB ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
236.0 KiB src/taxonomy/core-filter-definitions-by-group.json
226.1 KiB ../node_modules/.pnpm/posthog-js@1.407.2/node_modules/posthog-js/dist/module.js
154.3 KiB ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
105.8 KiB src/lib/api.ts
94.0 KiB ../packages/quill/packages/quill/dist/index.js
93.3 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js
90.6 KiB ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js

Posted automatically by check-eager-graph · sizes are eager output bytes (shipped, post-tree-shake) from the esbuild metafile · part of #32479

Toolbar bundle — eager 2.18 MiB within budget

What the toolbar ships to customer pages, measured from the esbuild output (minified, post-tree-shake). The eager set is the entry plus everything statically imported from it — fetched before any feature runs; deferred chunks load lazily. The eager guardrail is 5.72 MiB. Each output file must also stay below 10 MB, where CloudFront stops compressing it. The module boundary is enforced separately by check-toolbar-graph.

Metric Size Δ vs base Budget
Eager (shipped)
entry + static imports
2.18 MiB · 17 files no change ████░░░░░░ 38.1% of 5.72 MiB
Deferred (lazy) 2.07 MiB · 33 files no change n/a — loads on demand
Loader dist/toolbar.js 1.1 KiB no change █░░░░░░░░░ 5.8% of 19.5 KiB
Largest eagerly-shipped chunks
Size File
713.8 KiB dist/toolbar/toolbar-app-HLTHZTTF.css
545.0 KiB dist/toolbar/chunk-chunk-6OSYGHA4.js
484.2 KiB dist/toolbar/chunk-chunk-FFAAFRZ5.js
133.6 KiB dist/toolbar/chunk-chunk-LYC3RDNL.js
131.8 KiB dist/toolbar/chunk-chunk-T5KY5WYR.js
71.0 KiB dist/toolbar/toolbar-app-THUTYU3T.js
69.0 KiB dist/toolbar/chunk-chunk-27JL52RE.js
35.6 KiB dist/toolbar/chunk-chunk-JD7XW4XC.js
20.9 KiB dist/toolbar/chunk-chunk-3VBOQT7S.js
12.2 KiB dist/toolbar/chunk-chunk-PIK3PADE.js

Posted automatically by check-toolbar-size · sizes are toolbar output bytes (shipped, post-tree-shake) from the esbuild metafile

Dist folder size — no change

Total size of the built frontend/dist folder (all assets), compared against the base branch.

Total: 1352.29 MiB · no change

@Gilbert09 Gilbert09 added the stamphog Request AI approval (no full review) label Jul 24, 2026 — with PostHog

@stamphog stamphog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small, well-tested error-classification fix that follows an established, widely-used pattern (get_retryable_errors) already present in five other sources; low risk, outside risky territory, with a regression test proving the marker matches the actual raised message.

  • 👍 on the PR from hex-security-app[bot].
  • Diff includes an incidental generated-file change in products/experiments/frontend/generated/api.schemas.ts (additive read-only fields is_system/was_impersonated/client) not mentioned in the description — appears to be generated-file drift, not authored behavior, and is purely additive/non-behavioral so not a blocker.
Gate mechanics and policy version
Gate Result
prerequisites all clear
deny-list no deny categories matched
size 6L, 1F substantive, 26L/3F incl. docs/generated/snapshots — within ceiling
tier T1-agent / T1b-small (26L, 3F, single-area, fix)
stamphog 2.0.0b3 .stamphog/policy.yml @ 8f47666 · reviewed head 5d915b1

@Gilbert09
Gilbert09 merged commit 0980277 into master Jul 24, 2026
373 checks passed
@Gilbert09
Gilbert09 deleted the posthog-code/fix-notion-5xx-retryable-error-tracking-noise branch July 24, 2026 15:31
@deployment-status-posthog

deployment-status-posthog Bot commented Jul 24, 2026

Copy link
Copy Markdown

Deploy status

Environment Status Deployed At Workflow
dev ✅ Deployed 2026-07-24 15:57 UTC Run
prod-us ✅ Deployed 2026-07-24 16:13 UTC Run
prod-eu ✅ Deployed 2026-07-24 16:17 UTC Run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stamphog Request AI approval (no full review)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant