GeminiGemini
SandboxGet API key
  • Crypto Trading
  • Prediction Markets
  • SDKs & Tools
Changelog
Gemini Crypto Exchange LogoGemini Crypto Exchange Logo

© 2026 Gemini Space Station, Inc.

Overview
TypeScript SDK
    QuickstartAuthenticationWebSocketError HandlingPatterns & Recipes
    API Reference
    Deep Dives
TypeScript SDK

TypeScript SDK — Error Handling

The SDK uses typed error classes so you can catch specific failure modes. Every SDK error extends SdkError.

Error class hierarchy

Code
SdkError Base class for all SDK errors ├── ApiError Any non-2xx REST response │ ├── InvalidRequest 400 — malformed or rejected request │ ├── InvalidNonce 400 — nonce reused or not increasing │ ├── MissingNonce 400 — nonce not present in payload │ ├── InvalidSignature 400 — HMAC signature mismatch │ ├── MissingRole 403 — API key lacks required role │ ├── AcceptTermsRequired 403 — must accept terms before trading │ ├── NotFoundError 404 — resource does not exist │ ├── InsufficientFunds 406 — not enough balance │ ├── RateLimitError 429 — rate limit exceeded │ └── ServiceUnavailable 5xx — exchange down or errored ├── ValidationError Request body fails documented shape check ├── ConnectionError WebSocket open failed or dropped ├── WebSocketRequestError Non-success WebSocket method response ├── RequestTimeoutError Operation exceeded deadline ├── RequestAbortedError Caller cancelled via AbortSignal ├── OAuthStateError OAuth callback state mismatch ├── OAuthAuthorizationError OAuth authorization denied ├── OAuthTokenError OAuth token endpoint failure ├── EndpointMismatch Internal: payload path mismatch └── ResyncRequiredError Order book gap detected

Catching errors

Catch broadly or narrowly depending on your needs:

Code
import { SdkError, ApiError, RateLimitError, AcceptTermsRequired, } from "gemini-markets/server"; try { await client.predictions.placeOrder({ /* ... */ }); } catch (err) { if (err instanceof AcceptTermsRequired) { // User must accept terms first await client.predictions.acceptTerms(); // retry... } else if (err instanceof RateLimitError) { // Back off and retry console.log("Rate limited, status:", err.status); } else if (err instanceof ApiError) { // Any other API error console.log(err.status, err.reason, err.code, err.category); } else if (err instanceof SdkError) { // SDK-level error (timeout, connection, validation) console.log(err.message); } }

Error metadata

Every ApiError carries structured fields for programmatic handling:

Code
catch (err) { if (err instanceof ApiError) { err.status; // HTTP status code (400, 403, 429, etc.) err.reason; // Server error string ("InvalidNonce", "RateLimit", etc.) err.code; // Stable SDK code ("invalid_request", "rate_limited", etc.) err.category; // Error family ("validation", "authentication", "rate_limit", etc.) err.serverCode; // Raw server error code, if present err.metadata; // Request metadata (endpoint, method, correlation ID, status) } }

The code and category fields are stable across SDK versions — use them for programmatic branching. The reason field is the verbatim server string and may change.

Retries

The SDK retries automatically for generated safe-read operations only (GET-equivalent endpoints). Retries trigger on:

  • Network failures
  • HTTP 429 (rate limit) — respects Retry-After header
  • HTTP 502, 503, 504 (transient server errors)

Mutating operations are never retried. A failed order placement stays failed — you decide whether to retry.

Configure retry behavior:

Code
const client = await createClient({ auth, maxRetries: 3, // default: 5 backoff: { baseMs: 500, // default: 500 capMs: 15_000, // default: 30_000 factor: 2, // default: 2 }, });

Safe error serialization

Use serializeError() to log errors safely. It strips raw response bodies and credentials while preserving structure:

Code
import { serializeError } from "gemini-markets/server"; try { await client.trading.createNewOrder({ /* ... */ }); } catch (err) { // Safe for logging — no secrets, no raw bodies console.log(JSON.stringify(serializeError(err))); // Include raw body only for debugging (treat as sensitive) console.log(serializeError(err, { includeRawBody: true })); }

The serialized output includes: name, message (redacted), status, reason (only recognized values), code, category, metadata (endpoint, method, correlation ID), and operationContext.

Diagnostics

The SDK emits structured diagnostic events across REST, OAuth, WebSocket, and order-book operations. Diagnostics are silent by default.

Diagnostic listener

Receive every event as a structured object:

Code
const client = await createClient({ auth, onDiagnostic: (event) => { // event.level: "debug" | "info" | "warn" | "error" // event.component: "rest" | "oauth" | "websocket" | "order_book" // event.name: specific event name // event.response: safe metadata (endpoint, status, correlation ID) myTelemetry.record(event); }, });

When using OAuthAuth, pass the same onDiagnostic callback to include token exchange and refresh events:

Code
const auth = new OAuthAuth({ // ... onDiagnostic: (event) => myTelemetry.record(event), });

Console logger

For development, use the built-in console logger:

Code
import { ConsoleLogger } from "gemini-markets/server"; const client = await createClient({ auth, logger: new ConsoleLogger({ minLevel: "debug" }), });

Log levels: debug, info, warn, error. Set minLevel to control verbosity.

What's redacted

Diagnostic events and serialized errors never include: request bodies, response bodies, credentials, signatures, tokens, API keys, or nonces. They do include: endpoint paths, HTTP methods, status codes, correlation IDs, exchange request IDs, rate-limit headers, retry counts, and content types.

Use serializeError(err, { includeRawBody: true }) only when you need the raw body for debugging, and treat that output as sensitive.

What's next

  • Patterns & recipes — timeouts, cancellation, pagination, and heartbeat
  • API Reference — all operations with their retry and validation behavior
  • WebSocket Sessions — reconnection and connection error recovery
  • Transport & Signing — retry policy internals
Last modified on August 14, 2026
WebSocketPatterns & Recipes
On this page
  • Error class hierarchy
  • Catching errors
  • Error metadata
  • Retries
  • Safe error serialization
  • Diagnostics
    • Diagnostic listener
    • Console logger
    • What's redacted
  • What's next
TypeScript
TypeScript
TypeScript
TypeScript
TypeScript
TypeScript
TypeScript