LiticaLitica
Docs/Error Handling

Python SDK

Error Handling

Everything the SDK raises inherits from LiticaError, so one except clause is a complete catch. Nothing is swallowed, nothing is reworded.

import time
import litica

try:
    client.add_memory("...")
except litica.LiticaRateLimitError as e:
    time.sleep(e.retry_after or 60)     # seconds, from the Retry-After header
except litica.LiticaError as e:
    print(e.status_code)   # 429, 422, ... or None for connection errors
    print(e.detail)        # the server's message, verbatim
    e.response             # the raw httpx.Response, when there is one

HTTP errors

A non-2xx response raises a subclass of LiticaAPIError chosen by status code:

ExceptionStatusMeaning
LiticaAuthError401 / 403Missing or invalid X-API-Key
LiticaNotFoundError404Unknown memory, namespace, or agent grant
LiticaConflictError409e.g. a namespace name that already exists
LiticaUnsupportedMediaError415A document type the server cannot parse
LiticaValidationError422Well-formed request, rejected contents
LiticaRateLimitError429Over the per-key budget; check .retry_after
LiticaServerError5xxServer-side failure
LiticaAPIErrorotherAny other non-2xx response

LiticaRateLimitError.retry_after is the server's Retry-After header in seconds, or None when it was not sent.

Errors raised without an HTTP response

LiticaConfigErrorClient constructed without something it needs (e.g. an API key)
LiticaConnectionErrorThe server could not be reached at all
LiticaTimeoutThe request ran out of time
LiticaResponseErrorThe server replied with a body the SDK could not read

LiticaResponseError is worth a note: it fires on a non-JSON success body, or a response missing a field the SDK treats as part of the contract (like a memory with no id). Unknown extra fields never raise — they stay reachable through .raw.

Two deliberate exceptions to the rule

  • health() returns False instead of raising when the server is unreachable — a health check that explodes is not much of a health check.
  • add_document with a path that does not exist raises a plain FileNotFoundError, the standard Python signal for that mistake.

Retries

v0.1.0 has no automatic retries. For production use, wrap calls with your retry library of choice and treat LiticaRateLimitError, LiticaTimeout, LiticaConnectionError, and LiticaServerError as the retryable set:

import litica
from tenacity import retry, retry_if_exception_type, wait_exponential, stop_after_attempt

RETRYABLE = (
    litica.LiticaRateLimitError,
    litica.LiticaTimeout,
    litica.LiticaConnectionError,
    litica.LiticaServerError,
)

@retry(
    retry=retry_if_exception_type(RETRYABLE),
    wait=wait_exponential(min=1, max=30),
    stop=stop_after_attempt(5),
)
def add(client, content):
    return client.add_memory(content)

Next steps