Skip to content

Error Handling

When an API call cannot be fulfilled, the cotbias SDK converts raw HTTP responses into clean, strongly typed Python exceptions.

All client exceptions inherit from :class:~cotbias.exceptions.CotApiError, allowing you to catch errors at either a granular or general level.


🌳 Exception Hierarchy

Exception
 └── CotApiError (Base exception for all API failures)
      ├── AuthenticationError      (HTTP 401 - Invalid/missing API key)
      ├── PermissionDeniedError    (HTTP 403 - Tier access denied)
      ├── NotFoundError            (HTTP 404 - Unknown market or resource)
      ├── RateLimitExceededError   (HTTP 429 - Rate limit / quota exhausted)
      └── ServerError              (HTTP 5xx - Upstream server error)

🛠 Exception Descriptions

Exception Class HTTP Status Common Cause Recommended Action
AuthenticationError 401 Missing, malformed, or expired COT_API_KEY. Verify the key in environment variables or client constructor.
PermissionDeniedError 403 Account does not have Quant Tier API privileges. Upgrade account tier at cot-bias-terminal.com.
NotFoundError 404 Symbol or report family not found in the COT universe. Call client.markets.list() to check valid symbols.
RateLimitExceededError 429 Exceeded 2,000 requests/day quota or burst limit. Inspect e.retry_after or wait for daily reset.
ServerError 500+ Temporary backend maintenance or database timeout. Handled automatically by retry middleware.

🔍 Inspecting Error Attributes

All CotApiError exceptions provide rich attributes for logging and alerting:

from cotbias import CotClient
from cotbias.exceptions import CotApiError, RateLimitExceededError

with CotClient() as client:
    try:
        data = client.inference.get("NONEXISTENT_TICKER")
    except RateLimitExceededError as e:
        print(f"Rate limited! Wait {e.retry_after} seconds.")
        print(f"Error code: {e.code}")
    except CotApiError as e:
        print(f"API Error ({e.status_code}): {e.message}")
        print(f"Machine code: {e.code}")
        print(f"Raw response: {e.response_body}")

🛡 Production Error Handling Pattern

Here is a recommended pattern for automated production trading services:

import logging
import time
from cotbias import CotClient
from cotbias.exceptions import (
    AuthenticationError,
    PermissionDeniedError,
    NotFoundError,
    RateLimitExceededError,
    ServerError,
    CotApiError,
)

logger = logging.getLogger("trading_bot")


def fetch_market_safe(client: CotClient, symbol: str):
    try:
        return client.inference.get(symbol)
    except AuthenticationError:
        logger.critical("FATAL: Invalid COT_API_KEY. Shutting down worker.")
        raise
    except PermissionDeniedError:
        logger.error("Subscription lacks Quant Tier API access.")
        return None
    except NotFoundError:
        logger.warning("Market '%s' not tracked in CFTC universe. Skipping.", symbol)
        return None
    except RateLimitExceededError as e:
        logger.warning("Daily quota reached. Sleeping for %d seconds...", e.retry_after)
        time.sleep(e.retry_after)
        return None
    except ServerError as e:
        logger.error("Upstream COT Bias server error after all retries: %s", e)
        return None
    except CotApiError as e:
        logger.error("Unexpected API error: %s", e)
        return None