Documentation Index Fetch the complete documentation index at: https://docs.baytos.ai/llms.txt
Use this file to discover all available pages before exploring further.
Error Handling
Learn how to handle errors, implement retry strategies, and build resilient applications with the Claro Python SDK.
Exception Hierarchy
The SDK provides a hierarchy of exceptions for different error types:
BaytAPIError (base class)
├── BaytAuthError (401, 403)
├── BaytNotFoundError (404)
├── BaytRateLimitError (429)
└── BaytValidationError (400)
All SDK exceptions inherit from BaytAPIError, allowing you to catch all SDK errors with a single handler.
Exception Types
BaytAuthError
Authentication and authorization errors (HTTP 401, 403):
from baytos.claro import BaytClient, BaytAuthError
try :
client = BaytClient( api_key = "invalid_key" )
prompt = client.get_prompt( "@workspace/test:v1" )
except BaytAuthError as e:
print ( f "Authentication failed: { e } " )
print ( "Please check your API key" )
Common causes:
Invalid or expired API key
Insufficient permissions
Workspace access denied
BaytNotFoundError
Resource not found errors (HTTP 404):
from baytos.claro import BaytClient, BaytNotFoundError
client = BaytClient( api_key = "your_api_key" )
try :
prompt = client.get_prompt( "@workspace/nonexistent:v1" )
except BaytNotFoundError as e:
print ( f "Prompt not found: { e } " )
print ( "Check the package name and version" )
Common causes:
Incorrect package name
Wrong version number
Prompt deleted or moved
No access to the workspace
BaytRateLimitError
Rate limit exceeded (HTTP 429):
from baytos.claro import BaytClient, BaytRateLimitError
import time
client = BaytClient( api_key = "your_api_key" )
try :
prompt = client.get_prompt( "@workspace/test:v1" )
except BaytRateLimitError as e:
print ( f "Rate limited: { e } " )
print ( "Waiting before retry..." )
time.sleep( 60 ) # Wait 1 minute
Note: The SDK automatically retries on 429 with exponential backoff. This exception is only raised after all retries are exhausted.
BaytValidationError
Invalid request parameters (HTTP 400):
from baytos.claro import BaytClient, BaytValidationError
client = BaytClient( api_key = "your_api_key" )
try :
# Invalid limit
result = client.list_prompts( limit = 200 )
except BaytValidationError as e:
print ( f "Validation error: { e } " )
Common causes:
Invalid package name format
Out of range parameters (e.g., limit > 100)
Missing required fields
BaytAPIError
Base exception for all API errors:
from baytos.claro import BaytClient, BaytAPIError
client = BaytClient( api_key = "your_api_key" )
try :
prompt = client.get_prompt( "@workspace/test:v1" )
except BaytAPIError as e:
print ( f "API error: { e } " )
# Catches all SDK errors
Includes:
Network errors
Server errors (5xx)
Timeout errors
All specific exceptions above
Basic Error Handling
Catch Specific Errors
Handle different error types appropriately:
from baytos.claro import (
BaytClient,
BaytAuthError,
BaytNotFoundError,
BaytRateLimitError,
BaytValidationError,
BaytAPIError
)
client = BaytClient( api_key = "your_api_key" )
try :
prompt = client.get_prompt( "@workspace/my-prompt:v1" )
print ( f "Success: { prompt.title } " )
except BaytAuthError:
# Handle authentication errors
print ( "Authentication failed. Check your API key." )
print ( "Get a new key at: https://claro.baytos.ai" )
except BaytNotFoundError:
# Handle not found errors
print ( "Prompt not found. Check the package name." )
except BaytRateLimitError:
# Handle rate limiting
print ( "Rate limit exceeded. Please wait and try again." )
except BaytValidationError as e:
# Handle validation errors
print ( f "Invalid request: { e } " )
except BaytAPIError as e:
# Handle other API errors
print ( f "API error: { e } " )
except Exception as e:
# Handle unexpected errors
print ( f "Unexpected error: { e } " )
Catch All SDK Errors
Use the base exception to catch all SDK errors:
from baytos.claro import BaytClient, BaytAPIError
client = BaytClient( api_key = "your_api_key" )
try :
prompt = client.get_prompt( "@workspace/test:v1" )
except BaytAPIError as e:
# Handles all SDK exceptions
print ( f "SDK error: { e } " )
# Log to your error tracking system
Retry Strategies
Built-in Retries
The SDK automatically retries on rate limits and server errors:
from baytos.claro import BaytClient
# Default: 3 retries with exponential backoff
client = BaytClient( api_key = "your_api_key" , max_retries = 3 )
# Increase retries for unreliable networks
client = BaytClient( api_key = "your_api_key" , max_retries = 5 )
# Disable retries (not recommended)
client = BaytClient( api_key = "your_api_key" , max_retries = 0 )
The SDK retries on:
429 (Rate Limit) - Respects Retry-After header
5xx (Server Errors) - Uses exponential backoff
The SDK does NOT retry on:
4xx (Client Errors) - Except 429
Network Errors
Manual Retry Logic
Implement custom retry logic for specific operations:
import time
from baytos.claro import BaytClient, BaytAPIError
def get_prompt_with_retry ( client , package_name , max_attempts = 3 ):
"""Get prompt with manual retry logic"""
for attempt in range (max_attempts):
try :
return client.get_prompt(package_name)
except BaytAPIError as e:
if attempt == max_attempts - 1 :
# Last attempt - raise the error
raise
# Wait before retrying (exponential backoff)
wait_time = 2 ** attempt
print ( f "Error: { e } " )
print ( f "Retrying in { wait_time } seconds... (attempt { attempt + 1 } / { max_attempts } )" )
time.sleep(wait_time)
# Usage
client = BaytClient( api_key = "..." )
prompt = get_prompt_with_retry(client, "@workspace/test:v1" )
Retry with Decorators
Use a decorator for reusable retry logic:
import time
from functools import wraps
from baytos.claro import BaytAPIError
def retry_on_error ( max_attempts = 3 , delay = 1 ):
"""Decorator to retry on BaytAPIError"""
def decorator ( func ):
@wraps (func)
def wrapper ( * args , ** kwargs ):
for attempt in range (max_attempts):
try :
return func( * args, ** kwargs)
except BaytAPIError as e:
if attempt == max_attempts - 1 :
raise
wait_time = delay * ( 2 ** attempt)
time.sleep(wait_time)
return None
return wrapper
return decorator
# Usage
@retry_on_error ( max_attempts = 3 , delay = 1 )
def fetch_prompt ( client , package_name ):
return client.get_prompt(package_name)
client = BaytClient( api_key = "..." )
prompt = fetch_prompt(client, "@workspace/test:v1" )
Graceful Degradation
Provide fallbacks when operations fail:
from baytos.claro import BaytClient, BaytNotFoundError
def get_prompt_with_fallback ( client , primary_package , fallback_package = None ):
"""Try primary prompt, fall back to alternative if not found"""
try :
return client.get_prompt(primary_package)
except BaytNotFoundError:
if fallback_package:
print ( f "Primary prompt not found, using fallback: { fallback_package } " )
try :
return client.get_prompt(fallback_package)
except BaytNotFoundError:
print ( "Fallback prompt also not found" )
raise
raise
# Usage
client = BaytClient( api_key = "..." )
prompt = get_prompt_with_fallback(
client,
"@workspace/custom-support:v2" ,
fallback_package = "@workspace/generic-support:v1"
)
Logging Errors
Integrate with Python’s logging system:
import logging
from baytos.claro import BaytClient, BaytAPIError
# Configure logging
logging.basicConfig(
level = logging. INFO ,
format = ' %(asctime)s - %(name)s - %(levelname)s - %(message)s '
)
logger = logging.getLogger( __name__ )
def fetch_prompt_safely ( package_name ):
"""Fetch prompt with comprehensive logging"""
client = BaytClient( api_key = "..." )
try :
logger.info( f "Fetching prompt: { package_name } " )
prompt = client.get_prompt(package_name)
logger.info( f "Successfully fetched: { prompt.title } " )
return prompt
except BaytAPIError as e:
logger.error( f "Failed to fetch prompt { package_name } : { e } " )
raise
# Usage
try :
prompt = fetch_prompt_safely( "@workspace/test:v1" )
except BaytAPIError:
# Error already logged
pass
Error Context
Provide helpful error messages to users:
from baytos.claro import (
BaytClient,
BaytAuthError,
BaytNotFoundError,
BaytRateLimitError,
BaytAPIError
)
def get_user_friendly_error ( error ):
"""Convert SDK errors to user-friendly messages"""
if isinstance (error, BaytAuthError):
return (
"Authentication failed. Please check your API key. "
"You can generate a new key at: "
"https://claro.baytos.ai"
)
elif isinstance (error, BaytNotFoundError):
return (
"The requested prompt was not found. "
"Please verify the package name and version."
)
elif isinstance (error, BaytRateLimitError):
return (
"You've made too many requests. "
"Please wait a few minutes before trying again."
)
elif isinstance (error, BaytAPIError):
return (
"An error occurred while communicating with Claro. "
"Please try again later."
)
else :
return f "An unexpected error occurred: { error } "
# Usage
client = BaytClient( api_key = "..." )
try :
prompt = client.get_prompt( "@workspace/test:v1" )
except Exception as e:
error_message = get_user_friendly_error(e)
print (error_message)
Complete Example
#!/usr/bin/env python3
"""
Robust error handling example
"""
import os
import sys
import logging
import time
from baytos.claro import (
BaytClient,
BaytAuthError,
BaytNotFoundError,
BaytRateLimitError,
BaytValidationError,
BaytAPIError
)
# Configure logging
logging.basicConfig(
level = logging. INFO ,
format = ' %(asctime)s - %(levelname)s - %(message)s '
)
logger = logging.getLogger( __name__ )
def fetch_prompt_robust ( package_name , max_retries = 3 ):
"""Fetch prompt with comprehensive error handling"""
client = BaytClient( api_key = os.getenv( "BAYT_API_KEY" ))
for attempt in range (max_retries):
try :
logger.info( f "Fetching prompt: { package_name } (attempt { attempt + 1 } / { max_retries } )" )
prompt = client.get_prompt(package_name)
logger.info( f "Successfully fetched: { prompt.title } " )
return prompt
except BaytAuthError as e:
logger.error( f "Authentication failed: { e } " )
logger.error( "Please check your BAYT_API_KEY environment variable" )
sys.exit( 1 ) # Don't retry auth errors
except BaytNotFoundError as e:
logger.error( f "Prompt not found: { e } " )
logger.error( f "Package name: { package_name } " )
sys.exit( 1 ) # Don't retry not found errors
except BaytValidationError as e:
logger.error( f "Invalid request: { e } " )
sys.exit( 1 ) # Don't retry validation errors
except BaytRateLimitError as e:
if attempt < max_retries - 1 :
wait_time = 60 * (attempt + 1 )
logger.warning( f "Rate limited: { e } " )
logger.warning( f "Waiting { wait_time } seconds before retry..." )
time.sleep(wait_time)
else :
logger.error( "Rate limit exceeded and max retries exhausted" )
raise
except BaytAPIError as e:
if attempt < max_retries - 1 :
wait_time = 2 ** attempt
logger.warning( f "API error: { e } " )
logger.warning( f "Retrying in { wait_time } seconds..." )
time.sleep(wait_time)
else :
logger.error( f "API error after { max_retries } attempts: { e } " )
raise
except Exception as e:
logger.error( f "Unexpected error: { e } " )
raise
return None
if __name__ == "__main__" :
if len (sys.argv) < 2 :
print ( "Usage: python error_handling_example.py <package_name>" )
sys.exit( 1 )
package_name = sys.argv[ 1 ]
try :
prompt = fetch_prompt_robust(package_name)
if prompt:
print ( f " \n Prompt: { prompt.title } " )
print ( f "Version: { prompt.version } " )
print ( f " \n Content: \n { prompt.generator[: 200 ] } ..." )
except Exception as e:
logger.error( f "Failed to fetch prompt: { e } " )
sys.exit( 1 )
Best Practices
Catch Specific Exceptions First
Order exception handlers from most specific to most general: try :
prompt = client.get_prompt( "@workspace/test:v1" )
# ✅ Good: Specific first
except BaytNotFoundError:
print ( "Not found" )
except BaytAuthError:
print ( "Auth error" )
except BaytAPIError:
print ( "Other API error" )
# ❌ Bad: General first (specific handlers never reached)
except BaytAPIError:
print ( "API error" )
except BaytNotFoundError:
print ( "Not found" ) # Never reached!
Don't Retry on Client Errors
Only retry on transient errors: # ✅ Good: Retry on transient errors
if isinstance (e, (BaytRateLimitError, BaytAPIError)):
retry()
# ❌ Bad: Retry on auth errors (will always fail)
if isinstance (e, BaytAuthError):
retry() # Pointless - bad key won't become valid
Always log errors with context: import logging
logger = logging.getLogger( __name__ )
try :
prompt = client.get_prompt(package_name)
except BaytAPIError as e:
logger.error(
f "Failed to fetch prompt" ,
extra = {
'package_name' : package_name,
'error' : str (e),
'error_type' : type (e). __name__
}
)
raise
Provide User-Friendly Messages
Don’t expose technical errors to end users: # ✅ Good: User-friendly message
try :
prompt = client.get_prompt(pkg)
except BaytAuthError:
print ( "We couldn't verify your account. Please check your settings." )
# ❌ Bad: Technical error message
except BaytAuthError as e:
print ( f "BaytAuthError: { e } " ) # Confusing for users
Next Steps
Advanced Features Explore rate limiting and performance optimization
Client Configuration Configure retries and timeouts
API Reference Complete exception documentation
Quickstart Review basic usage patterns