Error Handling Patterns
Build safe, predictable fallback paths when trades don’t go as expected.
Philosophy
Trade execution can fail — due to market changes, balance issues, or API constraints. The goal is not to avoid all errors, but to handle them gracefully, log them clearly, and fail in ways that protect both your user and your business.
Common Error Types
Error Case | Status Code | Example Message | What It Means |
---|---|---|---|
Quote expired | 400 | "Quote expired" | The quote was valid, but not used within its expiry window |
Invalid asset pair | 400 | "Invalid asset pair" | Only usdt ↔ bitcoin swaps are supported |
Invalid or zero amount | 400 | "Missing or invalid amount" | Amount was not supplied or below threshold |
Duplicate reference | 409 | "Duplicate reference" | A trade already exists for this reference — idempotency caught it |
Insufficient balance | 422 | "Insufficient balance" | Wallet doesn’t have enough funds to complete trade |
Execution error | 500 | "Trade execution failed" | Internal error from liquidity routing or engine timeout |
Retry Logic
Idempotency is your safety net. If your system doesn’t receive a response due to timeout or network drop:
Retry the request using the same reference If the original succeeded, Bitnob returns the original trade If it failed previously, a 409 or error will be returned without re-execution
This guarantees no duplicate trades are created even under retry conditions.
Quote Expiry Handling
If you’re using quoteId:
You must execute the trade before the expiresAt timestamp
If the quote is expired:
Return a soft error to the user:
"This price has expired. Tap refresh to get a new quote."
Immediately request a fresh quote from /trades/quote
Monitoring Failures
To surface issues before they impact users:
Track all trade.failed webhook events
Alert on failure spikes (e.g., 5+ failures within 1 min)
Log the reason and context (wallet ID, amount, quote ID, chain, user ID)
Include the reference in all logs so issues can be traced across systems
Recovery Paths
Failure Case | Suggested Action |
---|---|
quote expired | Show new quote immediately, don’t auto-retry without user confirmation |
insufficient balance | Retry later or trigger background top-up, then queue trade |
duplicate reference | Treat as success if confirmed, log conflict if amounts differ |
execution error | Retry with backoff, optionally alert ops for trades over threshold |
Best Logging Practices
Log every failed trade attempt with:
reference
quoteId (if used)
input amount, source/destination asset failure code or message
createdAt timestamp user or account context
Use this to power dashboards, postmortems, and support flows.
Protecting Users
In all failure cases:
Do not deduct balances until trade.completed is confirmed
Clearly communicate when a trade failed and why
Never “freeze” funds unless you’ve locked execution in your internal system
Offer retry or refresh options in the UI, not silent fails