Skip to content

fix(google_ads): retry transient timeouts listing accessible accounts - #75902

Merged
talyn-app[bot] merged 1 commit into
masterfrom
posthog-code/google-ads-oauth-accounts-timeout-retry
Jul 31, 2026
Merged

fix(google_ads): retry transient timeouts listing accessible accounts#75902
talyn-app[bot] merged 1 commit into
masterfrom
posthog-code/google-ads-oauth-accounts-timeout-retry

Conversation

@Gilbert09

Copy link
Copy Markdown
Member

Problem

The Google Ads account picker (get_oauth_accounts) walks the full customer hierarchy through a chain of sequential REST calls to list accessible accounts. A single transient read timeout or connection error anywhere in that walk had no error handling and propagated as an unhandled exception, surfacing as a 500 and error-tracking noise instead of a clean, retryable message.

Changes

  • GoogleAdsIntegration.list_google_ads_accessible_accounts (used by both the warehouse source account picker and another Google Ads endpoint) now retries a transient Timeout/ConnectionError on each request, up to 3 attempts, before giving up.
  • The account picker (get_oauth_accounts) now catches an exhausted retry and raises the same actionable IntegrationAccountListingError the credential-rejection path already uses, instead of leaking a raw connection error.

How did you test this code?

  • Added test_accessible_accounts_rides_out_one_transient_read_timeout and test_accessible_accounts_raises_after_repeated_read_timeouts to TestGoogleAdsIntegrationModel: covers a single transient timeout succeeding on retry, and bounded retries still failing when the timeout persists.
  • Added TestGetOAuthAccountsNetworkErrorHandling::test_transient_network_error_becomes_actionable (parameterized over ReadTimeout/ConnectionError): covers the picker no longer leaking a raw exception.
  • Ran the affected suites locally: pytest posthog/models/test/test_integration_model.py -k GoogleAdsIntegrationModel (6 passed) and pytest products/warehouse_sources/backend/temporal/data_imports/sources/google_ads/tests/test_google_ads_source.py -k OAuthAccounts (3 passed).
  • ruff check / ruff format clean, uv run mypy --cache-fine-grained . clean, hogli ci:preflight --fix reports 0 failures.

Automatic notifications

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

Docs update

None needed. This is an internal resiliency fix with no user-facing config or documented workflow change.

🤖 Agent context

Autonomy: Fully autonomous

Written by Claude Code from a PostHog error tracking alert. Skills invoked: /writing-user-facing-copy, /writing-tests.

The exception (a ReadTimeout from googleads.googleapis.com) traced to GoogleAdsIntegration.list_google_ads_accessible_accounts in posthog/models/integration.py, called from the warehouse source's get_oauth_accounts in products/warehouse_sources/.../google_ads/source.py. That method walks the customer hierarchy with a chain of sequential HTTP requests and had no timeout resilience, unlike the source's gRPC sync path which already retries transient errors. I treated this as fixable fragility rather than a non-retryable user error: a single slow response anywhere in a long hierarchy walk shouldn't kill the whole account listing, and the failure isn't part of the sync pipeline's retry-classification path at all, so it wouldn't have been reachable via NonRetryableErrors.

Error tracking issue


Created with PostHog Code

The Google Ads account picker walks the customer hierarchy with a chain of sequential REST calls. Any single one of them hitting a read timeout or connection error failed the whole walk with an unhandled exception, surfacing as a 500 in error tracking instead of a clean, retryable message.

Retry each request on a transient timeout/connection error, and translate an exhausted retry into the same actionable error the credential-rejection path already raises.

Generated-By: PostHog Code
Task-Id: 0b7c1fd5-757e-430a-a97d-dbc99ad8d5c5
@trunk-io

trunk-io Bot commented Jul 31, 2026

Copy link
Copy Markdown

😎 This pull request was merged.

@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 31, 2026 09:33
@github-actions

Copy link
Copy Markdown
Contributor

🤖 CI report

⚠️ Playwright — 1 flaky

🎭 Playwright report · View test results →

⚠️ 1 flaky test:

  • Add a trend insight, expand it, verify data, and filter by date range (chromium)

These issues are not necessarily caused by your changes.
Annoyed by this section? Help fix flakies and failures and it will go green!

@Gilbert09 Gilbert09 added the stamphog Request AI approval (no full review) label Jul 31, 2026

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

Contained resiliency fix adding bounded retries and a clean error path for transient Google Ads network errors, owned by the author's own team, using an already-vendored dependency, with matching test coverage and no risky-territory surface touched.

  • Author wrote 0% of the modified lines and has 15 merged PRs in these paths (familiarity MODERATE).
  • 👍 on the PR from hex-security-app[bot].
Gate mechanics and policy version
Gate Result
prerequisites all clear
deny-list no deny categories matched
size 28L, 2F substantive, 89L/4F incl. docs/generated/snapshots — within ceiling
tier T1-agent / T1b-small (89L, 4F, two-areas, fix)
stamphog 2.0.0b4 .stamphog/policy.yml @ 74f316a · reviewed head 6e21437

@talyn-app
talyn-app Bot merged commit da0d8ec into master Jul 31, 2026
275 checks passed
@talyn-app
talyn-app Bot deleted the posthog-code/google-ads-oauth-accounts-timeout-retry branch July 31, 2026 10:54
@deployment-status-posthog

deployment-status-posthog Bot commented Jul 31, 2026

Copy link
Copy Markdown

Deploy status

Environment Status Deployed At Workflow
dev ✅ Deployed 2026-07-31 11:29 UTC Run
prod-us ✅ Deployed 2026-07-31 11:51 UTC Run
prod-eu ✅ Deployed 2026-07-31 11:51 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