This guide demonstrates robust error handling patterns for the Claro SDK. Proper error handling ensures your application remains stable and provides helpful feedback when issues occur.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.
Prerequisites
pip install baytos-claro
export BAYT_API_KEY="your_api_key_here"
Available Exception Types
The Claro SDK provides specific exception types:| Exception | When Raised | HTTP Status |
|---|---|---|
BaytAuthError | Invalid or missing API key | 401 |
BaytNotFoundError | Resource doesn’t exist | 404 |
BaytRateLimitError | Rate limit exceeded | 429 |
BaytAPIError | General API error | Various |
Example 1: Basic Error Handling
Handle the most common errors:import os
from baytos.claro import BaytClient, BaytNotFoundError, BaytAuthError, BaytAPIError
client = BaytClient(api_key=os.getenv("BAYT_API_KEY"))
try:
prompt = client.get_prompt("@workspace/my-prompt:v1")
print(f"Successfully loaded: {prompt.title}")
except BaytNotFoundError as e:
print(f"Prompt not found: {e}")
print("Check the package name and version")
except BaytAuthError as e:
print(f"Authentication failed: {e}")
print("Verify your API key is correct")
except BaytAPIError as e:
print(f"API error occurred: {e}")
print("Please try again later")
except Exception as e:
print(f"Unexpected error: {e}")
Example output when prompt not found
Example output when prompt not found
Prompt not found: Prompt not found: @workspace/my-prompt:v1
Check the package name and version
Example 2: Handle Missing API Key
Validate API key before making requests:import os
from baytos.claro import BaytClient, BaytAuthError
def get_client():
"""Initialize client with proper error handling"""
api_key = os.getenv("BAYT_API_KEY")
if not api_key:
print("Error: BAYT_API_KEY environment variable not set")
print("\nTo fix this:")
print("1. Get your API key from: https://claro.baytos.ai")
print("2. Set it with: export BAYT_API_KEY='your_api_key_here'")
exit(1)
try:
return BaytClient(api_key=api_key)
except ValueError as e:
print(f"Invalid API key format: {e}")
exit(1)
# Usage
client = get_client()
prompt = client.get_prompt("@workspace/my-prompt:v1")
Example 3: Retry Logic
Automatically retry failed requests:import os
import time
from baytos.claro import BaytClient, BaytRateLimitError, BaytAPIError
def get_prompt_with_retry(package_name, max_retries=3):
"""Fetch prompt with automatic retry"""
client = BaytClient(api_key=os.getenv("BAYT_API_KEY"))
for attempt in range(max_retries):
try:
return client.get_prompt(package_name)
except BaytRateLimitError as e:
if attempt < max_retries - 1:
wait_time = 2 ** attempt # Exponential backoff: 1s, 2s, 4s
print(f"Rate limited. Retrying in {wait_time}s...")
time.sleep(wait_time)
else:
print("Rate limit exceeded after all retries")
raise
except BaytAPIError as e:
if attempt < max_retries - 1:
print(f"API error. Retry {attempt + 1}/{max_retries}...")
time.sleep(1)
else:
print("Failed after all retries")
raise
# Usage
try:
prompt = get_prompt_with_retry("@workspace/my-prompt:v1")
print(f"Successfully loaded: {prompt.title}")
except Exception as e:
print(f"Failed to load prompt: {e}")
The SDK already includes automatic retry logic for rate limits. This example shows how to add additional retry logic for other scenarios.
Example 4: Graceful Degradation
Provide fallback behavior when prompts aren’t available:import os
from baytos.claro import BaytClient, BaytNotFoundError, BaytAPIError
def get_prompt_or_fallback(package_name, fallback_content):
"""Get prompt or use fallback"""
client = BaytClient(api_key=os.getenv("BAYT_API_KEY"))
try:
prompt = client.get_prompt(package_name)
return prompt.generator
except BaytNotFoundError:
print(f"Prompt not found, using fallback")
return fallback_content
except BaytAPIError as e:
print(f"API error, using fallback: {e}")
return fallback_content
# Usage
fallback = "You are a helpful assistant."
content = get_prompt_or_fallback("@workspace/assistant:v1", fallback)
print(f"Using content: {content[:50]}...")
Example 5: Validate Prompt Before Use
Check that a prompt has the expected structure:import os
from baytos.claro import BaytClient, BaytNotFoundError
class PromptValidationError(Exception):
"""Raised when prompt doesn't meet requirements"""
pass
def get_validated_prompt(package_name):
"""Get and validate prompt"""
client = BaytClient(api_key=os.getenv("BAYT_API_KEY"))
try:
prompt = client.get_prompt(package_name)
# Validate prompt has content
if not prompt.generator:
raise PromptValidationError("Prompt has no generator content")
# Validate minimum length
if len(prompt.generator) < 10:
raise PromptValidationError("Prompt content too short")
return prompt
except BaytNotFoundError:
raise PromptValidationError(f"Prompt not found: {package_name}")
# Usage
try:
prompt = get_validated_prompt("@workspace/my-prompt:v1")
print("Prompt is valid")
except PromptValidationError as e:
print(f"Validation failed: {e}")
exit(1)
Example 6: Handle File Download Errors
Robust error handling for file downloads:import os
from baytos.claro import BaytClient, BaytNotFoundError, BaytAPIError
client = BaytClient(api_key=os.getenv("BAYT_API_KEY"))
try:
# Get prompt
prompt = client.get_prompt("@workspace/prompt-with-files:v1")
# Check for files
if not prompt.has_context():
print("No files attached to this prompt")
exit(0)
files = prompt.get_file_contexts()
# Download each file
for file in files:
try:
print(f"Downloading {file.file_name}...")
content = client.download_context_file(file.id)
# Save file
with open(file.file_name, 'wb') as f:
f.write(content)
print(f"✓ Downloaded successfully ({len(content):,} bytes)")
except BaytNotFoundError:
print(f"✗ File not found: {file.file_name}")
except BaytAPIError as e:
print(f"✗ Download failed: {e}")
except IOError as e:
print(f"✗ Could not save file: {e}")
except BaytNotFoundError as e:
print(f"Prompt not found: {e}")
except Exception as e:
print(f"Unexpected error: {e}")
Example 7: Logging Errors
Proper error logging for debugging:import os
import logging
from baytos.claro import BaytClient, BaytAPIError, BaytNotFoundError
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
def get_prompt_with_logging(package_name):
"""Get prompt with comprehensive logging"""
client = BaytClient(api_key=os.getenv("BAYT_API_KEY"))
try:
logger.info(f"Fetching prompt: {package_name}")
prompt = client.get_prompt(package_name)
logger.info(f"Successfully loaded: {prompt.title}")
return prompt
except BaytNotFoundError as e:
logger.error(
f"Prompt not found: {package_name}",
extra={'error': str(e)}
)
raise
except BaytAPIError as e:
logger.error(
f"API error while fetching {package_name}",
extra={'error': str(e), 'error_type': type(e).__name__},
exc_info=True
)
raise
# Usage
try:
prompt = get_prompt_with_logging("@workspace/my-prompt:v1")
except Exception as e:
logger.critical("Failed to load prompt", exc_info=True)
Example 8: Custom Error Messages
Provide user-friendly error messages:import os
from baytos.claro import BaytClient, BaytNotFoundError, BaytAuthError, BaytRateLimitError
def get_user_friendly_error(error):
"""Convert exception to user-friendly message"""
if isinstance(error, BaytAuthError):
return (
"Authentication failed. Please check your API key.\n"
"Get a new key from: https://claro.baytos.ai"
)
if isinstance(error, BaytNotFoundError):
return (
"The requested prompt could not be found.\n"
"Please verify the package name and version."
)
if isinstance(error, BaytRateLimitError):
return (
"You've made too many requests. Please wait a moment.\n"
"Rate limits help ensure fair usage for all users."
)
return f"An unexpected error occurred: {error}"
# Usage
client = BaytClient(api_key=os.getenv("BAYT_API_KEY"))
try:
prompt = client.get_prompt("@workspace/my-prompt:v1")
print(f"Loaded: {prompt.title}")
except Exception as e:
print(get_user_friendly_error(e))
Example 9: Context Manager Pattern
Use context managers for resource cleanup:import os
from contextlib import contextmanager
from baytos.claro import BaytClient, BaytAPIError
@contextmanager
def prompt_context(package_name):
"""Context manager for prompt operations"""
client = BaytClient(api_key=os.getenv("BAYT_API_KEY"))
prompt = None
try:
prompt = client.get_prompt(package_name)
yield prompt
except BaytAPIError as e:
print(f"Error loading prompt: {e}")
raise
finally:
# Cleanup if needed
if prompt:
print(f"Finished with prompt: {prompt.title}")
# Usage
try:
with prompt_context("@workspace/my-prompt:v1") as prompt:
print(f"Using prompt: {prompt.title}")
# Do work with prompt
except Exception as e:
print(f"Failed: {e}")
Example 10: Batch Operations Error Handling
Handle errors when processing multiple prompts:import os
from baytos.claro import BaytClient, BaytNotFoundError, BaytAPIError
client = BaytClient(api_key=os.getenv("BAYT_API_KEY"))
package_names = [
"@workspace/prompt1:v1",
"@workspace/prompt2:v1",
"@workspace/nonexistent:v1", # This will fail
"@workspace/prompt3:v1"
]
successful = []
failed = []
for package_name in package_names:
try:
prompt = client.get_prompt(package_name)
successful.append(prompt)
print(f"✓ Loaded: {package_name}")
except BaytNotFoundError:
failed.append({'package': package_name, 'error': 'Not found'})
print(f"✗ Not found: {package_name}")
except BaytAPIError as e:
failed.append({'package': package_name, 'error': str(e)})
print(f"✗ Error: {package_name} - {e}")
print(f"\nSummary: {len(successful)} successful, {len(failed)} failed")
if failed:
print("\nFailed prompts:")
for item in failed:
print(f" - {item['package']}: {item['error']}")
Example 11: Timeout Handling
Handle timeout scenarios:import os
import signal
from contextlib import contextmanager
from baytos.claro import BaytClient, BaytAPIError
class TimeoutError(Exception):
pass
@contextmanager
def timeout(seconds):
"""Context manager for timeout"""
def signal_handler(signum, frame):
raise TimeoutError(f"Operation timed out after {seconds}s")
# Set the signal handler
signal.signal(signal.SIGALRM, signal_handler)
signal.alarm(seconds)
try:
yield
finally:
signal.alarm(0) # Disable the alarm
# Usage
client = BaytClient(api_key=os.getenv("BAYT_API_KEY"))
try:
with timeout(5): # 5 second timeout
prompt = client.get_prompt("@workspace/my-prompt:v1")
print(f"Loaded: {prompt.title}")
except TimeoutError as e:
print(f"Request timed out: {e}")
except BaytAPIError as e:
print(f"API error: {e}")
The timeout example uses Unix signals and won’t work on Windows. For cross-platform timeouts, use threading or async patterns.
Example 12: Comprehensive Error Handler
Production-ready error handling wrapper:import os
import logging
import time
from functools import wraps
from baytos.claro import (
BaytClient,
BaytAuthError,
BaytNotFoundError,
BaytRateLimitError,
BaytAPIError
)
logger = logging.getLogger(__name__)
def with_error_handling(max_retries=3, fallback=None):
"""Decorator for comprehensive error handling"""
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
last_error = None
for attempt in range(max_retries):
try:
return func(*args, **kwargs)
except BaytAuthError as e:
logger.error(f"Authentication failed: {e}")
raise # Don't retry auth errors
except BaytNotFoundError as e:
logger.error(f"Resource not found: {e}")
raise # Don't retry not found errors
except BaytRateLimitError as e:
if attempt < max_retries - 1:
wait_time = 2 ** attempt
logger.warning(f"Rate limited. Retrying in {wait_time}s...")
time.sleep(wait_time)
last_error = e
continue
raise
except BaytAPIError as e:
if attempt < max_retries - 1:
logger.warning(f"API error. Retry {attempt + 1}/{max_retries}")
time.sleep(1)
last_error = e
continue
raise
except Exception as e:
logger.error(f"Unexpected error: {e}", exc_info=True)
raise
# All retries exhausted
if fallback is not None:
logger.warning(f"Using fallback after {max_retries} retries")
return fallback
raise last_error
return wrapper
return decorator
# Usage
@with_error_handling(max_retries=3)
def get_prompt(package_name):
client = BaytClient(api_key=os.getenv("BAYT_API_KEY"))
return client.get_prompt(package_name)
try:
prompt = get_prompt("@workspace/my-prompt:v1")
print(f"Loaded: {prompt.title}")
except Exception as e:
print(f"Failed: {e}")
Next Steps
API Errors
Complete API error reference
Rate Limits
Understanding rate limits
Basic Usage
Basic SDK examples
Advanced Patterns
Production patterns