chore: back-merge main → dev (20260616) — withdraw + send dead-button hotfixes (#2224, #2225)#2228
Conversation
handleAmountContinue threw 'Failed to get country from bank account' inside
the onClick when getCountryFromAccount returned undefined. A synchronous throw
in a click handler aborts the router transition with zero UI feedback — the
button just goes dead ('press Continue, nothing happens'). Surfaced as a
customer report + Sentry incomplete-app-router-transaction (6 users/14d).
Three changes make the handler correct-by-construction:
- Route Manteca (AR/BR) accounts by method type BEFORE the generic saved-bank
branch. Manteca accounts also set selectedBankAccount, so they previously
fell into that branch and either mis-routed to the Bridge bank page or threw.
- Replace the throw with setError + console.error so an unresolved country is a
recoverable, visible error, not a dead button.
- Add a terminal else that sets an error, so no selected-method shape can ever
leave the handler having done nothing.
The real country-resolution fix is the API counterpart (Manteca flat metadata
shape); this is the defense-in-depth that guarantees the symptom can't recur.
Adds the first tests for the no-country path and Manteca routing — the harness
previously mocked getCountryFromAccount to always succeed, so this path was
entirely uncovered.
…t-clean Avoid adding a no-require-imports eslint error: drive the bridge.utils mock through a hoisted mock fn (matching the file's mockUseWallet idiom) instead of require()-ing the mocked module inside the test.
CodeRabbit nit: the component destructures spendableBalance; the harness default mocked the wrong key (balance), leaving maxDecimalAmount=0 for existing tests.
PaymentMethodActionList renders an 'Exchange or Wallet' card (soon:false, so enabled) whose tap only does anything when the caller passes onPayWithExternalWallet. The semantic-request flow passes it; the direct-send flow (SendInputView, non- logged-in users) does NOT — and direct-send has no external-wallet path at all (only Input/Status/Success views). So a guest who entered an amount and tapped the card got nothing: a dead button (audit HIGH finding, same class as the withdraw Continue throw). Fix at the component level so it's correct-by-construction for every caller: only render the exchange-or-wallet card when an onPayWithExternalWallet handler is provided. No caller can surface a card it can't honor. Semantic-request is unchanged (still passes the handler). Adds the component's first tests.
…-no-throw fix(withdraw): Continue button can never silently die (no-throw + correct Manteca routing)
…let-dead-card fix(send): hide 'Exchange or Wallet' dead-button card in direct-send flow
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Caution Review failedPull request was closed or merged during review WalkthroughThe withdraw page's ChangesWithdraw Continue-button routing fixes
PaymentMethodActionList exchange-or-wallet visibility fix
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint install timed out. The project may have too many dependencies for the sandbox. Comment |
Code-analysis diffPainscore total: 5796.9 → 5797.23 (+0.33) 🆕 New findings (10)
✅ Resolved (10)
|
🧪 UI test report — ✅ all greenSuites
📊 Coverage (unit)
⏱ 10 slowest test cases
|
Back-merges the prod hotfixes merged to
mainintodevso the next dev→main release doesn't conflict.Carries:
fix(withdraw): Continue button can never silently die(no-throw + Manteca routing + tests)fix(send): hide 'Exchange or Wallet' dead-button card(+ tests)Clean merge (0 conflicts) — both changed files were identical on dev and main. No
dev-side architecture to graft.