Error Handling
The SDK provides structured error types to help you handle failures gracefully. This page covers the error hierarchy and best practices for error handling.
Error Types
| Error Type | Description |
|---|---|
ApiError | Server returned an error response (4xx, 5xx) |
ClientValidationError | Request data failed validation |
AuthenticationError | Authentication failed |
Importing Errors
from credoai.errors import ApiError, ClientValidationError
from credoai.auth import AuthenticationError
Handling API Errors
ApiError is raised when the server returns an error response:
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 Code | Meaning |
|---|---|
| 400 | Bad Request - Invalid request data |
| 401 | Unauthorized - Invalid or missing credentials |
| 403 | Forbidden - Insufficient permissions |
| 404 | Not Found - Resource doesn't exist |
| 409 | Conflict - Resource already exists |
| 422 | Validation Error - Invalid field values |
| 429 | Rate Limited - Too many requests |
| 500 | Server Error - Internal error |
Handling Validation Errors
ClientValidationError is raised when request data fails validation before being sent:
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
AuthenticationError is raised when authentication fails:
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
Handle all error types in a single try block:
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
Error handling works the same way with the async client:
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
Log errors for debugging and monitoring:
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
- Learn about Async Operations
- See the API Reference for endpoint-specific errors