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 failed

Exception 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 context

AuthenticationError

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 valid

RateLimitError

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 reset

ValidationError

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 parameters

ResourceNotFoundError

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.details

AionvisionTimeoutError

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 again

UploadError

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 manually
results = await client.upload(files, raise_on_failure=False)
# Check for failures
if 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 failures
try:
results.raise_on_failures() # Returns self if no failures
except 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 details

ChatError

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 asyncio
from 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:
raise

Graceful 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,
}