Skip to main content
Every failure the exchange describes is a *rails.Error. It carries the operation, the status code, the Slug and Code from the Error Reference, the message, how long the exchange asked you to wait (RetryAfter), and the clientRequestId. The message is for people and may be reworded; the code never changes meaning, so branch on the code. The shared codes are rails.Code*, and each product’s are in its package, as perps.Code* and options.Code*.

Sentinels

What happened to the request itself is a sentinel, matched with errors.Is: A 502 or 504 over HTTP, or a context that ends mid-request, leaves the outcome unknown too. Each product’s Orders page shows how to find an order after a request got no answer.

Timeouts and Retries

Every call takes a context.Context, and its deadline is the only timeout the SDK applies. On HTTP it bounds the whole call, retries included. On the WebSocket, a command not answered by the deadline returns rails.ErrTimeout. HTTP reads are retried up to two more times on connection errors, 408, 429 and 5xx, after the wait the exchange asked for or with jittered backoff. Nothing that changes state is sent twice, over HTTP or the WebSocket, since the exchange rejects a reused clientRequestId as a duplicate or drops it. The exceptions are cancels, described on each product’s Orders page (Perpetuals, Options).