fix(fx): stop the add-money and withdraw screens freezing on a rate fetch - #2707
fix(fx): stop the add-money and withdraw screens freezing on a rate fetch#2707innolope-dev wants to merge 1 commit into
Conversation
…etch useCurrency seeded its currency code on the first render and then ignored the prop for the rest of its life. Both callers derive the currency from useSearchParams(), which is empty on the first render of a statically exported page, so the hook latched null, never fetched, and left the withdraw screen on a loader that could never resolve. Sync the code from the prop, and report the gap before the fetch starts as loading so consumers don't read it as a settled "no rate" and flash an error. A superseded in-flight request can no longer overwrite the current currency's rate either. The failure states were dead ends on top of that: the hook only refetched when the currency changed, so a rate outage stranded the user until they left the screen. Add refetch() and surface it through a shared RateUnavailable component in all three rate-dependent flows. withdraw had no error branch at all (a failed fetch fell into the same infinite loader), and the claim review step rendered "1 USD = undefined". Keep the header mounted while add-money loads so back always works. Fixes #1848
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
Code-analysis diffPainscore total: 7159.84 → 7161.12 (+1.28) 🆕 New findings (23)
…and 3 more. ✅ Resolved (20)
📈 Painscore deltas (top movers)
|
🧪 UI test report — ✅ all greenSuites
📊 Coverage (unit)
⏱ 10 slowest test cases
|
Fixes #1848.
What was already handled
Worth stating up front so the diff reads in context — most of the issue's suggested fix already landed:
fetchWithSentryaborts at 20s (client) with one silent GET retry, and both/bridge/exchange-rateand/users/limitsgo through it.useLimitsretry. It inheritsRETRY_STRATEGIES.FAST(2 retries, exponential backoff) from the appQueryClient.InputAmountStepwas fixed in fix(add-money): stop page crash when FX rate fails to load (PEANUT-UI-PS7) #2325.So the remaining freeze was not a missing timeout.
The actual freeze
useCurrencyseededcodefrom the prop on the first render and then ignored the prop for the rest of its life — there was no sync effect. Both callers derive the currency fromuseSearchParams():withdraw/manteca/page.tsx→useCurrency(selectedCountry?.currency ?? null)MantecaAddMoney.tsx→useCurrency(selectedCountry?.currency ?? 'ARS')On the first render of a statically exported page the search params are empty, so the withdraw page passed
null, the hook latched it, never fetched, andpricestayed null forever. Its gate isif (isCurrencyLoading || !currencyPrice || …) return <PeanutLoading />— an unresolvable loader with no header and no way out. That's a deterministic hang rather than a slow network, which fits "reproducible on G31 and G23" better than a timeout would.The same latch also meant add-money would price a Brazil flow in ARS (its fallback) whenever the country arrived a render late.
Changes
useCurrencycodewhen the prop changes, tracking the previous prop so the unsupported-currency branch (which deliberately nullscode) isn't clobbered on the next render.isLoading, so consumers can't read it as a settled "no rate" and flash an error.refetch(). Previously the effect only re-ran on a currency change, so a rate outage stranded the user until they left the screen entirely.Failure states — new shared
RateUnavailable(alert + retry), wired into all three rate-dependent flows:InputAmountStep: retry button instead of a bare alert; header stays mounted while loading so back always works.withdraw/manteca: had no error branch at all — a failed fetch fell into the same infinite loader. Now an error screen with back and retry.MantecaReviewStep: rendered1 USD = undefined ARS; now shows the retry state.i18n — moved
rateUnavailablefromaddMoney.errorsto the sharederrorsnamespace across all four catalogs rather than duplicating the string.Verification
useCurrencytests (late-arriving currency, refetch recovery, out-of-order response) and 2 newInputAmountSteptests.next buildsucceeds; 1089 static pages generated.tsc,eslint, andprettierclean on the touched files.Not covered
No page-level test for
withdraw/manteca— it has no existing suite and would need a large mock surface. The hook test covers the root cause; the page's new branch is not directly exercised.