Appearance
Errors
How Cash App failures surface in React and what to do at each step.
How errors surface
- Hook
errorstate —useCashAppSupportedAssets().error,useCashAppOrder().error, amount validation viauseCashAppAmount().error. - Thrown / rejected promises —
createOrder/refetchalso reject. - Events —
useOnCashAppOrderFailedanduseOnCashAppOrderExpiredare not errors, but you must handle them in UI.
Amount validation errors
useCashAppAmount().error is an AmountValidationError ({ code, message, metadata }), not a string. Switch on code for i18n:
tsx
import type { AmountValidationError } from '@swapped/connect-sdk'
import { useCashAppAmount } from '@swapped/connect-sdk/react'
function AmountError() {
const { error } = useCashAppAmount()
if (!error) return null
const text = translateAmountError(error)
return <p>{text}</p>
}
function translateAmountError(error: AmountValidationError): string {
switch (error.code) {
case 'below_min':
return `Min amount ${error.metadata.formattedMinAmount}`
case 'above_spendable':
return `Max amount ${error.metadata.formattedMaxAmount}`
case 'above_balance':
return `Balance is ${error.metadata.formattedBalanceAmount}`
default:
return error.message
}
}Typed SDK failures are ConnectSdkError with a stable code:
tsx
import { ConnectSdkError, ConnectSdkErrorCode } from '@swapped/connect-sdk'
import { useCashAppOrder } from '@swapped/connect-sdk/react'
function CreateWithErrors() {
const { createOrder, error, isCreating } = useCashAppOrder()
async function onSubmit() {
try {
await createOrder()
} catch (err) {
if (
err instanceof ConnectSdkError &&
err.code === ConnectSdkErrorCode.SESSION_NOT_ACTIVE
) {
// Call restartSession() via useSwappedConnectClient()
}
}
}
return (
<div>
{error && <p>{error.message}</p>}
<button type="button" disabled={isCreating} onClick={() => void onSubmit()}>
Pay
</button>
</div>
)
}When things fail in the flow
| Step | What goes wrong | How you see it | What to do in UI |
|---|---|---|---|
| Mount hooks | Outside CashAppProvider | REACT_CASH_APP_PROVIDER_REQUIRED | Wrap with the provider |
| Load assets | API / network failure | assets error / API_ERROR | Retry refetch |
| Create order | Incomplete selection | CASH_APP_SELECTION_INCOMPLETE (createOrder() only) | Select asset and amount, or pass a request |
| Create order | Session already completed | SESSION_NOT_ACTIVE | restartSession() first |
| Create order | Session not loaded | SESSION_REQUIRED | loadSession() |
| Create order | API rejection | API_ERROR | Fix amount / retry |
| Waiting | Payment failed | useOnCashAppOrderFailed / isFailed | Failed UI; create a new order |
| Waiting | Timed out | useOnCashAppOrderExpired / isExpired | Toast + navigate back; create a new order |
| After success | Create again without restart | SESSION_NOT_ACTIVE | restartSession() |
Block amounts below minAmountFiat with useCashAppAmount before createOrder.
Error code reference
| Code | When it happens | What to do |
|---|---|---|
REACT_CASH_APP_PROVIDER_REQUIRED | Hook used outside CashAppProvider | Wrap with CashAppProvider |
CASH_APP_SELECTION_INCOMPLETE | createOrder() without asset / amount | Complete selection first, or pass a request |
SESSION_REQUIRED | No loaded session | Call loadSession() |
SESSION_NOT_ACTIVE | Session cannot accept a new payment | restartSession() before createOrder |
API_ERROR | Assets / create failure | Retry |
CLIENT_DESTROYED | Client already destroyed | Create a new client |