Documentation
Error Handling
Handle errors gracefully with typed exceptions
Single Import Pattern
The SDK provides specific exception types for different error conditions. All exceptions AND types are available as class attributes on AionVision and SyncAionVision, so you only need a single import. Access via AionVision.AuthenticationError, AionVision.DescriptionStatus, etc.
Basic Error Handling
Catch and handle common errors
from aion import AionVision
try: result = await client.upload("image.jpg")except AionVision.AuthenticationError: print("Invalid API key")except AionVision.RateLimitError as e: print(f"Rate limited. Retry after {e.retry_after} seconds")except AionVision.QuotaExceededError as e: print(f"Quota exceeded: {e.details.get('available')}/{e.details.get('limit')} available")except AionVision.ValidationError as e: print(f"Invalid request: {e.message}") print(f"Details: {e.details}")except AionVision.AionvisionError as e: print(f"API error: {e.code} - {e.message}")Exception Hierarchy
AionvisionError (base)├── AuthenticationError # Invalid API key (401)├── AionvisionPermissionError # Insufficient permissions (403)├── ResourceNotFoundError # Resource not found (404)├── ValidationError # Invalid request data (400/422)├── QuotaExceededError # Upload/API quota exceeded (403)├── RateLimitError # Too many requests (429)├── AionvisionTimeoutError # Operation timed out├── ServerError # Server-side error (5xx)├── AionvisionConnectionError # Network connection failed├── CircuitBreakerError # Circuit breaker open (repeated failures)├── UploadError # Upload operation failed├── DescriptionError # Description generation failed├── DocumentProcessingError # Document processing failed├── CloudStorageError # Cloud storage operation failed├── ChatError # Chat operation failed├── BatchError # Batch operation failed└── SSEStreamError # SSE streaming connection failedException Details
AionvisionError (Base)
All SDK exceptions inherit from this
class AionvisionError(Exception): code: str # Error code (e.g., "AUTH_ERROR") message: str # Human-readable message details: dict[str, Any] # Additional contextAuthenticationError
Invalid or missing API key
try: result = await client.upload("image.jpg")except AionVision.AuthenticationError as e: print(f"Authentication failed: {e.message}") # Check your API key and ensure it's validRateLimitError
API rate limit exceeded
import asyncio
try: result = await client.upload("image.jpg")except AionVision.RateLimitError as e: print(f"Rate limited: {e.message}") print(f"Retry after: {e.retry_after} seconds") print(f"Limit: {e.limit}, Remaining: {e.remaining}, Reset: {e.reset}")
# Wait and retry await asyncio.sleep(e.retry_after or 5) result = await client.upload("image.jpg")QuotaExceededError
Upload or API quota exceeded
try: result = await client.upload("image.jpg")except AionVision.QuotaExceededError as e: print(f"Quota exceeded: {e.message}") print(f"Available: {e.details.get('available')}") print(f"Limit: {e.details.get('limit')}")
# For batch uploads, partial_results contains files uploaded before quota hit if e.partial_results: print(f"Partial results: {e.partial_results.summary()}") # Upgrade plan or wait for quota resetValidationError
Invalid request parameters
try: result = await client.upload("unsupported_file.bmp")except AionVision.ValidationError as e: print(f"Validation error: {e.message}") print(f"Details: {e.details}") # Fix the request parametersResourceNotFoundError
Requested resource doesn't exist
try: details = await client.files.get(file_id="nonexistent")except AionVision.ResourceNotFoundError as e: print(f"Not found: {e.message}") # Resource type and ID are in e.detailsAionvisionTimeoutError
Operation timed out
try: result = await client.upload( "large_image.jpg", description_timeout=10.0 # Very short timeout )except AionVision.AionvisionTimeoutError as e: print(f"Timed out: {e.message}") print(f"Last result: {e.last_result}") # Increase timeout or try againUploadError
Upload operation failed
try: result = await client.upload("image.jpg")except AionVision.UploadError as e: print(f"Upload failed: {e.message}") print(f"Filename: {e.details.get('filename')}") print(f"Stage: {e.details.get('stage')}")
# session_id can be used to recover results manually if e.session_id: print(f"Session ID: {e.session_id}")
# For batch uploads, partial_results contains files uploaded before failure if e.partial_results: print(f"Partial results: {e.partial_results.summary()}")DescriptionError
Description generation failed during upload
try: result = await client.upload("image.jpg", raise_on_failure=True)except AionVision.DescriptionError as e: print(f"Description failed: {e.message}") print(f"Image ID: {e.details.get('image_id')}") print(f"Status: {e.details.get('status')}")Batch Upload Failure Handling
Handle failures in batch uploads without exceptions
# Upload with raise_on_failure=False to handle failures manuallyresults = await client.upload(files, raise_on_failure=False)
# Check for failuresif results.has_failures: print(f"Summary: {results.summary()}") # "2 succeeded, 1 failed"
for r in results.failed(): print(f"{r.filename}: {r.description_error}") if r.description_is_retryable: print(" -> Can retry")
# Get only retryable failures for r in results.retryable(): print(f"Retryable: {r.image_id}")
# Opt-in to raise DescriptionError on failurestry: results.raise_on_failures() # Returns self if no failuresexcept AionVision.DescriptionError as e: print(f"Batch had failures: {e.message}")Note
By default, upload() raises DescriptionError for description failures (raise_on_failure=True). Set raise_on_failure=False to handle failures manually using results.raise_on_failures() or inspection methods.
BatchError
Batch operation failed
try: status = await client.batch.wait_for_completion(batch_id="...")except AionVision.BatchError as e: print(f"Batch failed: {e.message}") print(f"Batch ID: {e.details.get('batch_id')}") # Check individual results for detailsChatError
Chat operation failed
try: async with client.chat_session() as session: response = await session.send("Query")except AionVision.ChatError as e: print(f"Chat failed: {e.message}") print(f"Session ID: {e.details.get('session_id')}") print(f"Error code: {e.code}")Retry Pattern
Implement custom retry logic
import asynciofrom aion import AionVision
async def upload_with_retry(client: AionVision, file, max_attempts=3): for attempt in range(max_attempts): try: return await client.upload(file)
except AionVision.RateLimitError as e: if attempt < max_attempts - 1: wait = e.retry_after or (2 ** attempt) print(f"Rate limited, waiting {wait}s...") await asyncio.sleep(wait) else: raise
except (AionVision.ServerError, AionVision.AionvisionConnectionError) as e: if attempt < max_attempts - 1: wait = 2 ** attempt print(f"Transient error, retrying in {wait}s...") await asyncio.sleep(wait) else: raiseGraceful Degradation
Handle failures gracefully
from aion import AionVision
async def safe_upload(client: AionVision, image): """Upload image with fallback for errors.""" try: result = await client.upload_one(image) return { "success": True, "image_id": result.image_id, "description": result.description, }
except AionVision.QuotaExceededError: return { "success": False, "error": "quota_exceeded", "message": "API quota exceeded, please try later", }
except (AionVision.AionvisionTimeoutError, AionVision.ServerError) as e: return { "success": False, "error": "temporary", "message": f"Temporary error: {e.message}", }
except AionVision.AionvisionError as e: return { "success": False, "error": e.code, "message": e.message, }