Skip to content

refactor(remote-config): Disable /v1/config for the session on a 4xx response#3700

Merged
tonidero merged 1 commit into
mainfrom
disable_remote_config_on_4xx
Jul 3, 2026
Merged

refactor(remote-config): Disable /v1/config for the session on a 4xx response#3700
tonidero merged 1 commit into
mainfrom
disable_remote_config_on_4xx

Conversation

@tonidero

@tonidero tonidero commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Disables the /v1/config remote config endpoint for the rest of the session when the backend returns a 4xx, so no further config requests or blob fetches are made until the app restarts. The disabled state is exposed via RemoteConfigManager.isUnavailable.

Android equivalent of RevenueCat/purchases-ios#7118


Note

Medium Risk
Changes when the SDK hits /v1/config and prefetches blobs for an entire session after client errors; behavior is intentional but affects remote-config-dependent features until restart.

Overview
Remote config failures now carry an explicit retry vs disable signal from Backend.getRemoteConfig, aligned with workflows/offerings-style error handling.

Backend classifies errors as SHOULD_RETRY (transport, 5xx, bad parse on 2xx) or SHOULD_DISABLE (4xx client refusal) and passes that on the onError callback via new GetRemoteConfigErrorHandlingBehavior.

RemoteConfigManager sets a session-scoped kill-switch on SHOULD_DISABLE, exposes isUnavailable, and skips further /v1/config refreshes (and thus blob prefetch) until app restart. clearCache() does not clear the disable flag—treated as app/endpoint-level, not per-user.

Unit and integration tests cover 4xx/5xx behavior, retry after transient errors, and disable surviving identity changes.

Reviewed by Cursor Bugbot for commit 8cfe71a. Bugbot is set up for automated code reviews on this repo. Configure here.

@tonidero tonidero changed the title Disable /v1/config for the session on a 4xx response refactor(remote-config): Disable /v1/config for the session on a 4xx response Jul 2, 2026
@tonidero tonidero force-pushed the disable_remote_config_on_4xx branch from 7c29eff to e96009b Compare July 2, 2026 12:13
@tonidero tonidero force-pushed the phase_6_rearm_blob_sources_when_exhausted branch from 760450f to 54e2307 Compare July 2, 2026 12:13
@tonidero tonidero changed the base branch from phase_6_rearm_blob_sources_when_exhausted to graphite-base/3700 July 2, 2026 12:25
@tonidero tonidero marked this pull request as ready for review July 2, 2026 12:35
@tonidero tonidero requested a review from a team as a code owner July 2, 2026 12:35

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit e96009b. Configure here.

@tonidero tonidero force-pushed the disable_remote_config_on_4xx branch from e96009b to 5659295 Compare July 2, 2026 14:15
@tonidero tonidero changed the base branch from graphite-base/3700 to phase_6_rearm_blob_sources_when_exhausted July 2, 2026 14:15
@codecov

codecov Bot commented Jul 2, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 85.71429% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 80.58%. Comparing base (90387d7) to head (8cfe71a).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
.../kotlin/com/revenuecat/purchases/common/Backend.kt 84.61% 1 Missing and 1 partial ⚠️
...rchases/common/remoteconfig/RemoteConfigManager.kt 87.50% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3700      +/-   ##
==========================================
+ Coverage   80.55%   80.58%   +0.02%     
==========================================
  Files         395      395              
  Lines       16300    16316      +16     
  Branches     2318     2322       +4     
==========================================
+ Hits        13131    13148      +17     
  Misses       2243     2243              
+ Partials      926      925       -1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Base automatically changed from phase_6_rearm_blob_sources_when_exhausted to main July 2, 2026 16:33
vegaro added a commit that referenced this pull request Jul 3, 2026
…orkflow path

RemoteConfigManager.isUnavailable (the /v1/config 4xx session kill switch
from #3700) had no consumers. Expose it through the orchestrator and an
@InternalRevenueCatAPI property on Purchases (getter @JvmSynthetic-hidden
from the Java surface, like the sibling workflow functions), surface it
on the ui module's PurchasesType, and read it in PaywallViewModel at
fetch time: when the endpoint is session-disabled and the offering
carries a renderable fallback, render the offerings-provided paywall
directly instead of attempting the doomed workflow fetch. With no
fallback to render, the fetch is still attempted — a previously-committed
workflow can still serve from the local config cache, which beats
erroring without trying.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@rickvdl rickvdl left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Awesome work!

My only question is if we should make this consistent

@tonidero tonidero added this pull request to the merge queue Jul 3, 2026
Merged via the queue into main with commit 8e31cbf Jul 3, 2026
37 checks passed
@tonidero tonidero deleted the disable_remote_config_on_4xx branch July 3, 2026 09:13
vegaro added a commit that referenced this pull request Jul 3, 2026
…orkflow path

RemoteConfigManager.isUnavailable (the /v1/config 4xx session kill switch
from #3700) had no consumers. Expose it through the orchestrator and an
@InternalRevenueCatAPI property on Purchases (getter @JvmSynthetic-hidden
from the Java surface, like the sibling workflow functions), surface it
on the ui module's PurchasesType, and read it in PaywallViewModel at
fetch time: when the endpoint is session-disabled and the offering
carries a renderable fallback, render the offerings-provided paywall
directly instead of attempting the doomed workflow fetch. With no
fallback to render, the fetch is still attempted — a previously-committed
workflow can still serve from the local config cache, which beats
erroring without trying.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
vegaro added a commit that referenced this pull request Jul 3, 2026
…orkflow path

RemoteConfigManager.isUnavailable (the /v1/config 4xx session kill switch
from #3700) had no consumers. Expose it through the orchestrator and an
@InternalRevenueCatAPI property on Purchases (getter @JvmSynthetic-hidden
from the Java surface, like the sibling workflow functions), surface it
on the ui module's PurchasesType, and read it in PaywallViewModel at
fetch time: when the endpoint is session-disabled and the offering
carries a renderable fallback, render the offerings-provided paywall
directly instead of attempting the doomed workflow fetch. With no
fallback to render, the fetch is still attempted — a previously-committed
workflow can still serve from the local config cache, which beats
erroring without trying.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants