errors — Error types

All errors raised by the SDK are subclasses of O2Error. The error hierarchy maps directly to the error codes defined in the O2 Exchange API.

Base exception

class o2_sdk.errors.O2Error(message, code=None, reason=None, receipts=None)[source]

Base exception for all O2 Exchange API errors.

Parameters:
  • message (str) – Human-readable error description.

  • code (int | None) – Numeric error code (see table below), or None for on-chain reverts.

  • reason (str | None) – On-chain revert reason string.

  • receipts (list | None) – Raw transaction receipts (for on-chain errors).

message: str
code: int | None
reason: str | None
receipts: list | None

Error code reference

Code

Exception class

Category

Recovery strategy

1000

InternalError

General

Retry with exponential backoff.

1001

InvalidRequest

General

Fix the request format.

1002

ParseError

General

Fix the request body.

1003

RateLimitExceeded

General

Wait 3–5 seconds, then retry. The SDK handles this automatically with up to 3 retries.

1004

GeoRestricted

General

Region not allowed.

2000

MarketNotFound

Market

Verify the market ID or pair string.

2001

MarketPaused

Market

Wait for the market to resume.

2002

MarketAlreadyExists

Market

Market already exists.

3000

OrderNotFound

Order

Verify the order ID.

3001

OrderNotActive

Order

The order is already closed or canceled.

3002

InvalidOrderParams

Order

Check price, quantity, and order type.

4000

InvalidSignature

Account/Session

Check your signing method (personalSign vs rawSign).

4001

InvalidSession

Account/Session

Create a new session.

4002

AccountNotFound

Account/Session

Call setup_account().

4003

WhitelistNotConfigured

Account/Session

Account needs whitelisting (done automatically by setup_account()).

5000

TradeNotFound

Trade

Verify the trade ID.

5001

InvalidTradeCount

Trade

Invalid trade count parameter.

6000

AlreadySubscribed

WebSocket

Already subscribed to this topic.

6001

TooManySubscriptions

WebSocket

Reduce the number of active subscriptions.

6002

SubscriptionError

WebSocket

General subscription error.

7000

InvalidAmount

Validation

Check the amount value.

7001

InvalidTimeRange

Validation

Check the time range parameters.

7002

InvalidPagination

Validation

Check pagination parameters.

7003

NoActionsProvided

Validation

Include at least one action.

7004

TooManyActions

Validation

Maximum 5 actions per request.

8000

BlockNotFound

Block/Events

Block not found.

8001

EventsNotFound

Block/Events

Events not found for the specified block.

Special error types

class o2_sdk.errors.SessionExpired[source]

Client-side error raised when the session has expired before submitting an action. Create a new session.

This is detected locally by the SDK (no network call needed) by comparing the session’s expiry timestamp against the current time.

class o2_sdk.errors.OnChainRevert[source]

An on-chain transaction revert.

This error has no error code — it is distinguished by having a message and reason but no code field. Common revert reasons include:

  • NotEnoughBalance — Insufficient funds for the operation.

  • TraderNotWhiteListed — Account is not whitelisted.

  • InvalidPrice — Price violates on-chain constraints.

from o2_sdk import OnChainRevert

try:
    result = await client.create_order(...)
except OnChainRevert as e:
    print(f"Revert: {e.message}, reason: {e.reason}")

Error handling patterns

from o2_sdk import (
    O2Error, OrderSide,
    InvalidSignature,
    RateLimitExceeded,
    OnChainRevert,
    SessionExpired,
)

try:
    result = await client.create_order(
       "fFUEL/fUSDC", OrderSide.BUY, 0.02, 100.0
    )
except SessionExpired:
    # Create a new session
    session = await client.create_session(owner=owner, markets=["fFUEL/fUSDC"])
    result = await client.create_order(
       "fFUEL/fUSDC", OrderSide.BUY, 0.02, 100.0
    )
except InvalidSignature:
    # Check signing logic
    print("Signature verification failed")
except RateLimitExceeded:
    # SDK retries automatically, but you can add extra backoff
    await asyncio.sleep(5)
except OnChainRevert as e:
    print(f"On-chain revert: {e.reason}")
except O2Error as e:
    print(f"Error {e.code}: {e.message}")

Helper function

o2_sdk.errors.raise_for_error(data)[source]

Inspect a raw API response dict and raise the appropriate exception.

Handles both pre-flight validation errors (with code) and on-chain revert errors (with message + reason, no code). Does nothing if the response contains a tx_id (success).

Parameters:

data (dict) – Raw API response dict.