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