fix(ui): read SwapKit's error codes on the DEX amount screens - #1087
fix(ui): read SwapKit's error codes on the DEX amount screens#1087romchornyi wants to merge 1 commit into
Conversation
Every amount-related failure on Enter amount rendered as a dead end
("Something went wrong setting up your swap") even when SwapKit had said
exactly what was wrong. Two causes, both about where the code was read
from.
`decodeQuoteError` returned `body.message` before `body.error`, so the
prose reached the mapper and the code never did: "No routes found for
DASH.DASH -> BTC.BTC" does not match `noRoutesFound`, and the buy
screen's own `contains("noRoutesFound")` check missed it for the same
reason. And a failure a provider reports — an HTTP 200 with no routes
and `providerErrors[]` — was passed on as its prose alone, dropping
`errorCode`, the only stable identifier in the response.
Measured against api.swapkit.dev on 2026-08-28: at 0.05 DASH a
DASH -> BTC quote answers 200 with `sellAssetAmountTooSmall`; below
about 0.01 DASH it answers 404 `noRoutesFound`; above the pool's depth
it answers 200 with `apiRequestFailed`. All three read as "something
went wrong".
- `providerErrorMessage` puts the code back in front of the prose, so
provider-level and top-level failures reach the mapper the same way.
- Below-minimum codes are family-matched on an `AmountTooSmall` /
`AmountTooLow` suffix rather than enumerated, since SwapKit does not
document the per-provider vocabulary.
- `apiRequestFailed`, `invalidRoute`, `invalidAsset` and
`memoTooLongForSourceChain` are mapped; the last shares the copy the
wallet already uses when it catches an over-length memo locally.
- Routability probing classifies on codes too: a below-minimum reply
says the probe amount was too small, not that the asset is unroutable,
so the coin picker no longer hides an asset on that evidence.
- The convert screen's over-balance line follows the redesign to
"Max $205.32" (Figma 24034:44864).
Mirrors Android's `SwapKitErrors` (dashpay/dash-wallet#1526) and the
enter-amount copy from dashpay/dash-wallet#1539.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (5)
Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review. 📝 WalkthroughWalkthroughSwapKit errors now use normalized, case-insensitive codes for provider formatting, route classification, and amount validation. Buy and convert flows use shared error mapping. Localization adds below-minimum and shortened maximum-amount messages. ChangesSwapKit error flow
Estimated code review effort: 3 (Moderate) | ~25 minutes Merge Risk: ⚪ Minimal · up to The PR improves how existing SwapKit errors are classified and shown on swap amount screens without changing transaction authority, stored state, or external interfaces; no actionable merge-blocking risk remains beyond normal checks and review. Sequence Diagram(s)sequenceDiagram
participant SwapKitSwapProvider
participant SwapKitErrorCopy
participant BuyEnterAmountViewModel
participant SwapConvertViewModel
SwapKitSwapProvider->>SwapKitErrorCopy: Normalize provider error
SwapKitErrorCopy-->>SwapKitSwapProvider: Return error code and routability
SwapKitSwapProvider->>BuyEnterAmountViewModel: Return quote error
BuyEnterAmountViewModel->>SwapKitErrorCopy: Map validation message
SwapKitSwapProvider->>SwapConvertViewModel: Return API error
SwapConvertViewModel->>SwapKitErrorCopy: Map conversion message
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Full details: Docstring CoverageExplanation Docstring coverage is 31.58% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 19 functions across 4 files. (1 skipped: 1 unsupported.)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 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 |
|
🕓 Ready for review — 2 ahead in queue (commit c5eea1e) |
Issue being fixed or feature implemented
Reported from the Dash DEX Enter amount screens: the errors SwapKit returns had changed, and the screen answered almost everything with the same dead end — "Something went wrong setting up your swap" — even when the API had said exactly what was wrong.
Verified by hand against
api.swapkit.devon 2026-08-28. An amount below a route's floor comes back three different ways depending on how far below it is:200+providerErrors[0].errorCode = sellAssetAmountTooSmall404+error = noRoutesFound200+providerErrors[0].errorCode = apiRequestFailedTwo reasons none of it reached the user:
decodeQuoteErrorreturnedbody.messagebeforebody.error, so the prose reached the mapper and the code never did."No routes found for DASH.DASH -> BTC.BTC"does not matchnoRoutesFound, and the buy screen's owncontains("noRoutesFound")check missed it for the same reason — so even the one error that screen tried to handle fell through to the generic copy.providerErrors[]entry — was passed on as its prose alone, droppingerrorCode, the only stable identifier in the response.What was done?
Mirrors Android's
SwapKitErrors(dashpay/dash-wallet#1526) and the enter-amount copy from dashpay/dash-wallet#1539.providerErrorMessage(_:)renders a provider failure as"<code>: <detail>", so provider-level and top-level failures reach the mapper through one path.AmountTooSmall/AmountTooLowsuffix rather than enumerated — SwapKit doesn't document the per-provider vocabulary, and the prefix names whichever side was too small. Both forms carry "Amount", so an unrelated below-threshold code (a too-low fee) stays out.apiRequestFailed,invalidRoute,invalidAsset,memoTooLongForSourceChain. The last one shares the copy the wallet already shows when it catches an over-length memo locally before broadcasting.noRoutesFoundstill counts as conclusive.decodeQuoteErroris code-first, matching what the swap-side decoder already did.maya_max_amount_error).One string is removed: the buy screen's hand-rolled
dex_enter_amount_invalidfallback is orphaned now that both amount screens share the mapper.Not in this PR
MAYACHAIN,MAYACHAIN_STREAMINGandTHORCHAINanswerednoRoutesFoundfor every pair tried on 2026-08-28 — includingBTC.BTC -> ETH.ETH— while/tokensstill lists 31 and 18 assets for the two Maya providers.NEARandCHAINFLIPwork. That is upstream, not ours; tracked separately.How Has This Been Tested?
dashpaybuild,ARCHS=arm64, iOS Simulator SDK —BUILD SUCCEEDED.api.swapkit.devwith the app's own API key and request bodies (quote and swap, both directions, amount sweeps per asset), and the mapping checked against those recorded responses./v3/swapanswersinvalidRoutefor DASH → BTC even with SwapKit's ownnextActionspayload).Breaking Changes
None.
Checklist:
For repository code-owners and collaborators only
Summary by CodeRabbit