Error Handling¶
The Konigle SDK provides comprehensive error handling through a structured exception hierarchy. All exceptions inherit from the base KonigleError class, making it easy to catch and handle SDK-specific errors.
Exception Hierarchy¶
Base Exceptions¶
KonigleError- Base exception for all SDK errorsAPIError- Base for API-related errors with HTTP contextNetworkError- Network connectivity issuesKonigleTimeoutError- Request timeout errors
HTTP Status Code Exceptions¶
ValidationError(400) - Request validation failedAuthenticationError(401) - Invalid API keyAuthorizationError(403) - Insufficient permissionsNotFoundError(404) - Resource not foundConflictError(409) - Resource conflictRateLimitError(429) - Rate limit exceededServerError(5xx) - Server-side errors
Basic Error Handling¶
Catch All SDK Errors¶
import konigle
from konigle.exceptions import KonigleError
try:
client = konigle.Client(api_key="your-api-key")
image = client.images.get("img_123")
except KonigleError as e:
print(f"SDK error occurred: {e}")
except Exception as e:
print(f"Unexpected error: {e}")
Handle Specific Errors¶
from konigle.exceptions import (
AuthenticationError,
NotFoundError,
ValidationError,
RateLimitError
)
try:
client = konigle.Client(api_key="your-api-key")
image = client.images.create(image_data)
except AuthenticationError:
print("Invalid API key - please check your credentials")
except ValidationError as e:
print(f"Validation failed: {e}")
if e.field_errors:
for field, errors in e.field_errors.items():
print(f" {field}: {errors}")
except NotFoundError:
print("Resource not found")
except RateLimitError as e:
print(f"Rate limit exceeded: {e}")
if e.retry_after:
print(f"Retry after {e.retry_after} seconds")
Advanced Error Handling¶
API Error Details¶
All APIError exceptions include additional context:
from konigle.exceptions import APIError
try:
client.images.create(invalid_data)
except APIError as e:
print(f"Status Code: {e.status_code}")
print(f"Message: {e}")
print(f"Response: {e.response}")
Validation Error Details¶
ValidationError provides field-specific error information:
from konigle.exceptions import ValidationError
try:
image_data = ImageCreate(
name="", # Invalid: empty name
image="invalid.txt" # Invalid: not an image
)
except ValidationError as e:
print(f"General error: {e}")
# Access field-specific errors
for field, errors in e.field_errors.items():
print(f"Field '{field}': {errors}")
Rate Limit Handling¶
Handle rate limits with automatic retry:
import time
from konigle.exceptions import RateLimitError
def create_image_with_retry(client, image_data, max_retries=3):
for attempt in range(max_retries):
try:
return client.images.create(image_data)
except RateLimitError as e:
if attempt == max_retries - 1:
raise # Re-raise on final attempt
wait_time = e.retry_after or 60 # Default to 60s
print(f"Rate limited. Waiting {wait_time} seconds...")
time.sleep(wait_time)
Network Error Handling¶
Handle connectivity issues:
from konigle.exceptions import NetworkError, KonigleTimeoutError
def robust_api_call(client, operation_func, *args, **kwargs):
max_retries = 3
base_delay = 1
for attempt in range(max_retries):
try:
return operation_func(*args, **kwargs)
except KonigleTimeoutError:
print(f"Request timed out (attempt {attempt + 1})")
if attempt == max_retries - 1:
raise
time.sleep(base_delay * (2 ** attempt))
except NetworkError:
print(f"Network error (attempt {attempt + 1})")
if attempt == max_retries - 1:
raise
time.sleep(base_delay * (2 ** attempt))
# Usage
try:
result = robust_api_call(
client,
client.images.create,
image_data
)
except KonigleError as e:
print(f"Failed after retries: {e}")
Practical Patterns¶
Context Manager with Error Handling¶
from konigle.exceptions import KonigleError
class SafeKonigleClient:
def __init__(self, api_key):
self.api_key = api_key
self.client = None
def __enter__(self):
try:
self.client = konigle.Client(api_key=self.api_key)
return self.client
except AuthenticationError:
print("Authentication failed")
raise
except KonigleError as e:
print(f"Client initialization failed: {e}")
raise
def __exit__(self, exc_type, exc_val, exc_tb):
if self.client:
self.client.close()
# Usage
try:
with SafeKonigleClient("your-api-key") as client:
images = client.images.list()
except KonigleError:
print("Operation failed")
Async Error Handling¶
import asyncio
from konigle.exceptions import KonigleError
async def safe_async_operation():
try:
async with konigle.AsyncClient(api_key="your-api-key") as client:
image = await client.images.create(image_data)
return image
except ValidationError as e:
print(f"Validation error: {e}")
return None
except RateLimitError as e:
print(f"Rate limited: {e}")
if e.retry_after:
await asyncio.sleep(e.retry_after)
# Optionally retry here
return None
except KonigleError as e:
print(f"SDK error: {e}")
return None
result = asyncio.run(safe_async_operation())
Logging Integration¶
import logging
from konigle.exceptions import APIError, NetworkError
# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
def logged_api_operation(client, operation_name, operation_func, *args, **kwargs):
try:
logger.info(f"Starting {operation_name}")
result = operation_func(*args, **kwargs)
logger.info(f"{operation_name} completed successfully")
return result
except APIError as e:
logger.error(
f"{operation_name} API error: {e} "
f"(Status: {e.status_code})"
)
raise
except NetworkError as e:
logger.error(f"{operation_name} network error: {e}")
raise
except Exception as e:
logger.error(f"{operation_name} unexpected error: {e}")
raise
# Usage
try:
image = logged_api_operation(
client,
"Image Creation",
client.images.create,
image_data
)
except KonigleError:
# Error already logged
pass
Error Response Structure¶
API errors include structured response data:
try:
client.images.create(invalid_data)
except APIError as e:
# Response structure varies by error type
response = e.response
# Common fields
if "detail" in response:
print(f"Detail: {response['detail']}")
if "errors" in response:
for error in response["errors"]:
print(f"Error: {error}")
# Validation-specific fields
if isinstance(e, ValidationError):
for field, field_errors in e.field_errors.items():
print(f"Field {field}: {field_errors}")
Best Practices¶
- Always catch
KonigleErrorfor SDK-specific error handling - Handle authentication early - check API key validity on startup
- Implement retry logic for rate limits and network errors
- Log errors appropriately with sufficient context
- Validate data locally before API calls when possible
- Use specific exceptions for targeted error handling
- Provide user-friendly messages while preserving technical details for debugging