Skip to main content

Error Handling

The SDK provides structured error handling to help you manage failures gracefully. The approach differs between Python and TypeScript.

Error Types​

Python uses exception-based error handling with distinct error classes:

Error TypeDescription
ApiErrorServer returned an error response (4xx, 5xx)
ClientValidationErrorRequest data failed validation
AuthenticationErrorAuthentication failed
from credoai.errors import ApiError, ClientValidationError
from credoai.auth import AuthenticationError

Handling API Errors​

from credoai import CredoAI
from credoai.errors import ApiError

client = CredoAI()

try:
use_case = client.use_cases.get(use_case_id="non-existent-id")
except ApiError as e:
print(f"Status code: {e.status_code}")
print(f"Message: {e.message}")
print(f"Details: {e.details}")

Common Status Codes​

Status CodeMeaning
400Bad Request - Invalid request data
401Unauthorized - Invalid or missing credentials
403Forbidden - Insufficient permissions
404Not Found - Resource doesn't exist
409Conflict - Resource already exists
422Validation Error - Invalid field values
429Rate Limited - Too many requests
500Server Error - Internal error

Handling Validation Errors​

from credoai import CredoAI, UseCaseCreate
from credoai.errors import ClientValidationError

client = CredoAI()

try:
# Missing required field
client.use_cases.create(data=UseCaseCreate())
except ClientValidationError as e:
print(f"Validation failed: {e}")

Handling Authentication Errors​

from credoai import CredoAI
from credoai.auth import AuthenticationError

try:
client = CredoAI(api_key="invalid-key")
client.system.ping()
except AuthenticationError as e:
print(f"Authentication failed: {e}")

Comprehensive Error Handling​

from credoai import CredoAI, UseCaseCreate
from credoai.errors import ApiError, ClientValidationError
from credoai.auth import AuthenticationError

def create_use_case(name: str, description: str):
client = CredoAI()

try:
use_case = client.use_cases.create(
data=UseCaseCreate(name=name, description=description)
)
return use_case

except ClientValidationError as e:
print(f"Invalid data: {e}")
return None

except AuthenticationError as e:
print(f"Auth failed: {e}")
return None

except ApiError as e:
if e.status_code == 409:
print(f"Use case already exists: {name}")
elif e.status_code == 429:
print("Rate limited - try again later")
else:
print(f"API error ({e.status_code}): {e.message}")
return None

Retry Logic​

Implement retry logic for transient failures:

import time
from credoai import CredoAI
from credoai.errors import ApiError

def with_retry(func, max_retries=3, delay=1.0):
"""Execute a function with retry logic for transient failures."""
for attempt in range(max_retries):
try:
return func()
except ApiError as e:
if e.status_code == 429:
# Rate limited - wait and retry
wait_time = delay * (2 ** attempt)
print(f"Rate limited, waiting {wait_time}s...")
time.sleep(wait_time)
elif e.status_code >= 500:
# Server error - retry
wait_time = delay * (2 ** attempt)
print(f"Server error, retrying in {wait_time}s...")
time.sleep(wait_time)
else:
# Client error - don't retry
raise

raise Exception(f"Failed after {max_retries} attempts")

# Usage
client = CredoAI()
use_case = with_retry(lambda: client.use_cases.get(use_case_id="uc_abc123"))

Async Error Handling​

import asyncio
from credoai import AsyncCredoAI
from credoai.errors import ApiError

async def main():
async with AsyncCredoAI() as client:
try:
use_case = await client.use_cases.get(use_case_id="uc_abc123")
except ApiError as e:
print(f"Error: {e.status_code} - {e.message}")

asyncio.run(main())

Logging Errors​

import logging
from credoai import CredoAI
from credoai.errors import ApiError

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

client = CredoAI()

try:
response = client.use_cases.list()
except ApiError as e:
logger.error(
"API request failed",
extra={
"status_code": e.status_code,
"message": e.message,
"details": e.details
}
)
raise

Next Steps​