Error Handling¶
Both SDKs provide typed exception/error classes that map directly to API error codes.
Error Response Format¶
All API errors return:
{
"error": {
"code": "ERROR_CODE",
"message": "Human-readable description.",
"status": 401,
"details": {},
"request_id": "req_abc123",
"timestamp": "2026-02-19T12:00:00Z"
}
}
Python¶
from cloman import CloMan, CloManError
from cloman._exceptions import (
AuthenticationError,
AuthorizationError,
NotFoundError,
ValidationError,
RateLimitError,
ServerError,
TimeoutError,
)
client = CloMan(api_key="cloman_...")
try:
result = client.decide(context="Should we approve?")
except AuthenticationError as e:
# 401 — Invalid or expired API key
print(f"Auth failed: {e.message}")
except AuthorizationError as e:
# 403 — Key lacks required permissions
print(f"Not authorized: {e.message}")
except NotFoundError as e:
# 404 — Clone not found
print(f"Not found: {e.message}")
except ValidationError as e:
# 422 — Invalid request data
print(f"Validation error: {e.message}")
print(f"Details: {e.details}")
except RateLimitError as e:
# 429 — Rate limit exceeded
print(f"Rate limited: {e.message}")
if e.retry_after:
print(f"Retry after {e.retry_after}s")
except TimeoutError as e:
# Request timed out
print(f"Timeout: {e.message}")
except ServerError as e:
# 5xx — Server error (retries were exhausted)
print(f"Server error: {e.message}")
except CloManError as e:
# Catch-all for any other API error
print(f"[{e.code}] {e.message}")
TypeScript¶
import {
CloMan,
CloManError,
AuthenticationError,
AuthorizationError,
NotFoundError,
ValidationError,
RateLimitError,
ServerError,
TimeoutError,
} from "@clomanai/sdk";
const client = new CloMan("cloman_...");
try {
const result = await client.decide({ context: "Should we approve?" });
} catch (error) {
if (error instanceof AuthenticationError) {
// 401
console.error("Auth failed:", error.message);
} else if (error instanceof AuthorizationError) {
// 403
console.error("Not authorized:", error.message);
} else if (error instanceof NotFoundError) {
// 404
console.error("Not found:", error.message);
} else if (error instanceof ValidationError) {
// 422
console.error("Validation error:", error.message);
} else if (error instanceof RateLimitError) {
// 429
console.error("Rate limited:", error.message);
if (error.retryAfter) {
console.error(`Retry after ${error.retryAfter}s`);
}
} else if (error instanceof TimeoutError) {
console.error("Timeout:", error.message);
} else if (error instanceof ServerError) {
// 5xx
console.error("Server error:", error.message);
} else if (error instanceof CloManError) {
// Catch-all
console.error(`[${error.code}]`, error.message);
} else {
throw error; // Non-API error
}
}
Best Practices¶
- Catch specific errors first, then use
CloManErroras a catch-all. - Always handle
RateLimitError— it's the most common recoverable error. - Log the
request_id— it helps CloMan support debug issues. - Don't retry 4xx errors — they indicate a client-side problem that won't resolve by retrying.
- Let the SDK retry 5xx — both SDKs retry server errors automatically with exponential backoff.