- Thrown errors — the SDK throws a typed error (every class extends
OneSwapError). These happen at call time (swaps.createSwap,quotes.get, …) — for example a pair with no pool, an already-open swap, an invalid key, or a rate limit. - Terminal statuses — the swap is created successfully but ends in a non-success terminal state (
refunded,expired,failed). You read these off the swap’sstatus, not from a thrown error.
Typed errors
Every error extendsOneSwapError, which carries an optional status (HTTP status code) and data (the parsed response body). Catch by class with instanceof:
Terminal statuses
A created swap always reaches one of these terminal statuses. Readstatus (and amountOut / senderParty / error) off the swap:
The “already has an open swap” case
Only one open swap peruserRef is allowed. When you hit this, don’t create a duplicate — ask for the open swap and act on it. You don’t need to have stored the id: getOpenSwap finds it for you.
swap.id against your userRef at creation so you can always find the open swap again.
The “no direct pool” case
Every swap settles against one pool, and there is no multi-hop routing.quotes.get throws
NoDirectPoolError when no pool trades the pair — the error tells you both symbols so you can
route through an intermediate asset yourself:
Rate limits
Requests beyond a key’s per-minute tier throwRateLimitError (429). Create is the tightest tier; polling and reads are looser. Back off and retry:
waitForSwap (or a fixed poll interval) over tight polling loops so you stay under the limit.
A robust create-and-wait pattern
If
waitForSwap times out while a swap is still non-terminal, the swap may still settle. Resume
with getSwap(id) rather than treating it as failed.