fix(purchases): fail open only for Pro when feature-access config fails - #2625
Closed
mikib0 wants to merge 2 commits into
Closed
fix(purchases): fail open only for Pro when feature-access config fails#2625mikib0 wants to merge 2 commits into
mikib0 wants to merge 2 commits into
Conversation
Previously a failed feature-access config query returned undefined config, which hasFeatureAccess treats as 'not in early access' -> allowed for everyone, handing paid early-access features out for free on any fetch failure. Now on config error we fail open only for Pro members; non-Pro users are gated and see the paywall. A successfully-loaded config that omits a feature is still the graduated/unconfigured case and fails open for all.
Contributor
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
Contributor
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
packrat-admin | 6bffe7f | Commit Preview URL Branch Preview URL |
Jul 15 2026, 11:12 AM |
React Query's default networkMode 'online' parks a data-less query in fetchStatus 'paused' while offline: it never runs, never errors, and stays 'pending', so isLoading was true forever and EarlyAccessGate spun indefinitely with no connection. Treat a pending-but-paused query as settled (not loading), and treat a paused config query the same as an errored one: fail open for Pro, gate non-Pro. Surfaces isPending/fetchStatus through useEntitlement.
mikib0
force-pushed
the
feat/revenuecat-paywall-v2
branch
from
July 15, 2026 18:50
ea9cd68 to
df7bfe2
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Two related bugs in the early-access gate when the feature-access config can't be fetched:
Fail-open too broad. A failed config query returned
config = undefined;hasFeatureAccess(undefined, …)treats an absent feature as 'not in early access' →true, so any fetch failure handed paid early-access features to everyone for free.Infinite spinner offline. Neither the config nor customer-info query sets
networkMode, so React Query's default'online'mode parks a data-less query infetchStatus: 'paused'when the device is offline. It never runs, never errors, and stayspending— soisLoadingwastrueforever andEarlyAccessGatespun indefinitely with no connection.Fix
isPending && fetchStatus !== 'paused'), so the gate stops spinning offline.hasFeatureAccess.isPending/fetchStatusthroughuseEntitlement.Files:
useFeatureAccess.ts,useEntitlement.ts.Notes
PAYWALL_RESULT.ERROR, which the gate already handles withrouter.back(), so the user isn't trapped.CustomerInfofrom local cache offline, so the entitlement query generally resolves rather than pausing; the config (API) query is the one that pauses.packages/configis unchanged.