- Spec files
pypi-anthropic
Describes: pkg:pypi/anthropic@0.66.x
- Description
- The official Python library for the anthropic API
- Author
- tessl
- Last updated
errors.md docs/
1# Error Handling23The Anthropic SDK provides a comprehensive exception hierarchy for handling API errors, network issues, authentication problems, and service-specific errors. This enables robust error handling and appropriate responses to different failure scenarios.45## Capabilities67### Exception Hierarchy89All Anthropic SDK exceptions inherit from a base exception class, providing a structured approach to error handling.1011```python { .api }12class AnthropicError(Exception):13"""Base exception for all Anthropic SDK errors"""14pass1516class APIError(AnthropicError):17"""Base class for API-related errors"""18pass1920class APIStatusError(APIError):21"""HTTP status code errors"""22def __init__(self, message: str, *, response: httpx.Response, body: Optional[object]): ...2324@property25def status_code(self) -> int: ...26@property27def response(self) -> httpx.Response: ...28@property29def body(self) -> Optional[object]: ...3031class APITimeoutError(APIError):32"""Request timeout errors"""33pass3435class APIConnectionError(APIError):36"""Network connection errors"""37pass3839class APIResponseValidationError(APIError):40"""Response validation errors"""41pass42```4344### HTTP Status Errors4546Specific exception classes for different HTTP status codes and API error types.4748```python { .api }49class BadRequestError(APIStatusError):50"""HTTP 400 Bad Request errors"""51pass5253class AuthenticationError(APIStatusError):54"""HTTP 401 Authentication errors"""55pass5657class PermissionDeniedError(APIStatusError):58"""HTTP 403 Permission Denied errors"""59pass6061class NotFoundError(APIStatusError):62"""HTTP 404 Not Found errors"""63pass6465class ConflictError(APIStatusError):66"""HTTP 409 Conflict errors"""67pass6869class UnprocessableEntityError(APIStatusError):70"""HTTP 422 Unprocessable Entity errors"""71pass7273class RateLimitError(APIStatusError):74"""HTTP 429 Rate Limit errors"""75pass7677class InternalServerError(APIStatusError):78"""HTTP 500 Internal Server errors"""79pass80```8182### Error Response Types8384Structured error response objects that provide detailed error information.8586```python { .api }87class ErrorObject(TypedDict):88type: str89message: str9091class ErrorResponse(TypedDict):92type: Literal["error"]93error: ErrorObject9495class APIErrorObject(TypedDict):96type: str97message: str9899class AuthenticationError(TypedDict):100type: Literal["authentication_error"]101message: str102103class PermissionError(TypedDict):104type: Literal["permission_error"]105message: str106107class NotFoundError(TypedDict):108type: Literal["not_found_error"]109message: str110111class RateLimitError(TypedDict):112type: Literal["rate_limit_error"]113message: str114115class OverloadedError(TypedDict):116type: Literal["overloaded_error"]117message: str118119class BillingError(TypedDict):120type: Literal["billing_error"]121message: str122123class GatewayTimeoutError(TypedDict):124type: Literal["gateway_timeout_error"]125message: str126127class InvalidRequestError(TypedDict):128type: Literal["invalid_request_error"]129message: str130```131132## Usage Examples133134### Basic Error Handling135136```python137from anthropic import Anthropic, APIError, RateLimitError, AuthenticationError138139client = Anthropic()140141try:142message = client.messages.create(143model="claude-sonnet-4-20250514",144max_tokens=1024,145messages=[146{"role": "user", "content": "Hello!"}147]148)149print(message.content[0].text)150151except AuthenticationError as e:152print(f"Authentication failed: {e}")153print("Please check your API key")154155except RateLimitError as e:156print(f"Rate limit exceeded: {e}")157print("Please wait before making more requests")158159except APIError as e:160print(f"API error occurred: {e}")161print(f"Status code: {e.status_code}")162163except Exception as e:164print(f"Unexpected error: {e}")165```166167### Comprehensive Error Handler168169```python170import time171import logging172from typing import Optional, Any173174def handle_anthropic_request(175request_func: callable,176*args,177max_retries: int = 3,178backoff_factor: float = 1.0,179**kwargs180) -> Optional[Any]:181"""182Execute an Anthropic API request with comprehensive error handling and retries183"""184185for attempt in range(max_retries):186try:187return request_func(*args, **kwargs)188189except AuthenticationError as e:190logging.error(f"Authentication error: {e}")191print("❌ Authentication failed. Please check your API key.")192return None193194except PermissionDeniedError as e:195logging.error(f"Permission denied: {e}")196print("❌ Permission denied. Check your account permissions.")197return None198199except RateLimitError as e:200logging.warning(f"Rate limit exceeded (attempt {attempt + 1}): {e}")201if attempt < max_retries - 1:202wait_time = backoff_factor * (2 ** attempt)203print(f"⏳ Rate limited. Waiting {wait_time} seconds...")204time.sleep(wait_time)205continue206else:207print("❌ Rate limit exceeded. Max retries reached.")208return None209210except OverloadedError as e:211logging.warning(f"Service overloaded (attempt {attempt + 1}): {e}")212if attempt < max_retries - 1:213wait_time = backoff_factor * (2 ** attempt) * 2 # Longer wait for overload214print(f"⏳ Service overloaded. Waiting {wait_time} seconds...")215time.sleep(wait_time)216continue217else:218print("❌ Service overloaded. Max retries reached.")219return None220221except APITimeoutError as e:222logging.warning(f"Request timeout (attempt {attempt + 1}): {e}")223if attempt < max_retries - 1:224print(f"⏳ Request timed out. Retrying...")225continue226else:227print("❌ Request timeout. Max retries reached.")228return None229230except APIConnectionError as e:231logging.warning(f"Connection error (attempt {attempt + 1}): {e}")232if attempt < max_retries - 1:233wait_time = backoff_factor * (2 ** attempt)234print(f"⏳ Connection error. Retrying in {wait_time} seconds...")235time.sleep(wait_time)236continue237else:238print("❌ Connection error. Max retries reached.")239return None240241except BadRequestError as e:242logging.error(f"Bad request: {e}")243print(f"❌ Bad request: {e}")244print("Please check your request parameters.")245return None246247except NotFoundError as e:248logging.error(f"Resource not found: {e}")249print(f"❌ Resource not found: {e}")250return None251252except UnprocessableEntityError as e:253logging.error(f"Unprocessable entity: {e}")254print(f"❌ Request could not be processed: {e}")255return None256257except InternalServerError as e:258logging.error(f"Internal server error (attempt {attempt + 1}): {e}")259if attempt < max_retries - 1:260wait_time = backoff_factor * (2 ** attempt) * 3 # Longer wait for server errors261print(f"⏳ Server error. Retrying in {wait_time} seconds...")262time.sleep(wait_time)263continue264else:265print("❌ Server error. Max retries reached.")266return None267268except APIStatusError as e:269logging.error(f"API status error: {e} (Status: {e.status_code})")270print(f"❌ API error: {e}")271return None272273except APIError as e:274logging.error(f"General API error: {e}")275print(f"❌ API error: {e}")276return None277278except Exception as e:279logging.error(f"Unexpected error: {e}")280print(f"❌ Unexpected error: {e}")281return None282283return None284285# Usage286def create_message():287return client.messages.create(288model="claude-sonnet-4-20250514",289max_tokens=1024,290messages=[{"role": "user", "content": "Hello!"}]291)292293result = handle_anthropic_request(create_message, max_retries=3, backoff_factor=1.5)294if result:295print("✅ Request successful!")296print(result.content[0].text)297```298299### Streaming Error Handling300301```python302def safe_streaming_request(client: Anthropic, **kwargs) -> Optional[str]:303"""Handle errors in streaming requests"""304305try:306with client.messages.stream(**kwargs) as stream:307accumulated_text = ""308309try:310for text in stream.text_stream:311accumulated_text += text312print(text, end="", flush=True)313314return accumulated_text315316except Exception as stream_error:317print(f"\n❌ Streaming error: {stream_error}")318319# Try to get partial result320try:321partial_message = stream.get_final_message()322if partial_message and partial_message.content:323print("\n⚠️ Returning partial result...")324return partial_message.content[0].text325except:326pass327328return accumulated_text if accumulated_text else None329330except RateLimitError as e:331print(f"❌ Rate limit in streaming: {e}")332return None333334except APITimeoutError as e:335print(f"❌ Timeout in streaming: {e}")336return None337338except APIConnectionError as e:339print(f"❌ Connection error in streaming: {e}")340return None341342except APIError as e:343print(f"❌ API error in streaming: {e}")344return None345346# Usage347result = safe_streaming_request(348client,349model="claude-sonnet-4-20250514",350max_tokens=1024,351messages=[{"role": "user", "content": "Write a short story"}]352)353354if result:355print(f"\n✅ Streaming completed. Total characters: {len(result)}")356```357358### Custom Error Context359360```python361class AnthropicRequestContext:362"""Context manager for Anthropic requests with enhanced error reporting"""363364def __init__(self, operation_name: str, client: Anthropic):365self.operation_name = operation_name366self.client = client367self.start_time = None368369def __enter__(self):370self.start_time = time.time()371print(f"🚀 Starting {self.operation_name}...")372return self373374def __exit__(self, exc_type, exc_val, exc_tb):375duration = time.time() - self.start_time if self.start_time else 0376377if exc_type is None:378print(f"✅ {self.operation_name} completed in {duration:.2f}s")379else:380print(f"❌ {self.operation_name} failed after {duration:.2f}s")381382if issubclass(exc_type, AuthenticationError):383print("🔑 Authentication issue - check API key")384elif issubclass(exc_type, RateLimitError):385print("⏳ Rate limited - consider request pacing")386elif issubclass(exc_type, APITimeoutError):387print("⏰ Request timed out - consider shorter requests")388elif issubclass(exc_type, APIConnectionError):389print("🌐 Network issue - check internet connection")390elif issubclass(exc_type, OverloadedError):391print("🔥 Service overloaded - try again later")392elif issubclass(exc_type, APIError):393print(f"🔧 API error: {exc_val}")394else:395print(f"💥 Unexpected error: {exc_val}")396397# Don't suppress the exception398return False399400# Usage401with AnthropicRequestContext("Message Creation", client) as ctx:402message = client.messages.create(403model="claude-sonnet-4-20250514",404max_tokens=1024,405messages=[{"role": "user", "content": "Hello!"}]406)407print(message.content[0].text)408```409410### Error Logging and Monitoring411412```python413import json414from datetime import datetime415from pathlib import Path416417class AnthropicErrorLogger:418"""Logger for tracking and analyzing Anthropic API errors"""419420def __init__(self, log_file: str = "anthropic_errors.log"):421self.log_file = Path(log_file)422self.error_counts = {}423424def log_error(self, error: Exception, context: dict = None):425"""Log error with context information"""426427error_info = {428"timestamp": datetime.now().isoformat(),429"error_type": type(error).__name__,430"error_message": str(error),431"context": context or {}432}433434# Add specific error details435if isinstance(error, APIStatusError):436error_info["status_code"] = error.status_code437error_info["response_body"] = str(error.body) if error.body else None438439# Track error frequency440error_key = type(error).__name__441self.error_counts[error_key] = self.error_counts.get(error_key, 0) + 1442443# Write to log file444with open(self.log_file, "a") as f:445f.write(json.dumps(error_info) + "\n")446447print(f"📝 Error logged: {error_key}")448449def get_error_summary(self) -> dict:450"""Get summary of logged errors"""451return {452"total_errors": sum(self.error_counts.values()),453"error_counts": self.error_counts,454"most_common": max(self.error_counts.items(), key=lambda x: x[1]) if self.error_counts else None455}456457# Usage458error_logger = AnthropicErrorLogger()459460def logged_request(request_func, context: dict = None):461"""Execute request with error logging"""462try:463return request_func()464except Exception as e:465error_logger.log_error(e, context)466raise467468# Example usage469try:470result = logged_request(471lambda: client.messages.create(472model="claude-sonnet-4-20250514",473max_tokens=1024,474messages=[{"role": "user", "content": "Hello!"}]475),476context={"user_id": "user123", "request_type": "chat"}477)478except Exception:479pass480481# Get error summary482summary = error_logger.get_error_summary()483print(f"Error summary: {summary}")484```485486### Async Error Handling487488```python489import asyncio490from anthropic import AsyncAnthropic491492async def async_error_handler():493"""Demonstrate async error handling patterns"""494495client = AsyncAnthropic()496497try:498message = await client.messages.create(499model="claude-sonnet-4-20250514",500max_tokens=1024,501messages=[{"role": "user", "content": "Hello async world!"}]502)503504return message.content[0].text505506except RateLimitError as e:507print(f"Rate limited in async: {e}")508# Could implement async backoff here509await asyncio.sleep(5)510return None511512except APITimeoutError as e:513print(f"Async timeout: {e}")514return None515516except APIError as e:517print(f"Async API error: {e}")518return None519520# Usage521async def main():522result = await async_error_handler()523if result:524print(f"Async result: {result}")525526asyncio.run(main())527```