Overview
The Dedalus SDK provides a comprehensive exception hierarchy for handling different types of errors that can occur during API interactions. All exceptions inherit from the baseDedalusError class.
Exception hierarchy
DedalusError (base exception)
├── APIError
│ ├── APIStatusError (4xx and 5xx responses)
│ │ ├── BadRequestError (400)
│ │ ├── AuthenticationError (401)
│ │ ├── PermissionDeniedError (403)
│ │ ├── NotFoundError (404)
│ │ ├── ConflictError (409)
│ │ ├── UnprocessableEntityError (422)
│ │ ├── RateLimitError (429)
│ │ └── InternalServerError (5xx)
│ ├── APIConnectionError
│ │ └── APITimeoutError
│ └── APIResponseValidationError
├── LengthFinishReasonError
└── ContentFilterFinishReasonError
Importing exceptions
from dedalus_labs import (
DedalusError,
APIError,
APIStatusError,
BadRequestError,
AuthenticationError,
PermissionDeniedError,
NotFoundError,
ConflictError,
UnprocessableEntityError,
RateLimitError,
InternalServerError,
APIConnectionError,
APITimeoutError,
APIResponseValidationError,
)
from dedalus_labs._exceptions import (
LengthFinishReasonError,
ContentFilterFinishReasonError,
)
Common error patterns
Basic error handling
from dedalus_labs import Dedalus, APIError
client = Dedalus(api_key="your-api-key")
try:
response = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": "Hello!"}]
)
print(response.choices[0].message.content)
except APIError as e:
print(f"API error occurred: {e.message}")
print(f"Status code: {e.status_code}")
print(f"Request ID: {e.request_id}")
Handling specific status codes
from dedalus_labs import (
Dedalus,
AuthenticationError,
RateLimitError,
InternalServerError,
)
client = Dedalus(api_key="your-api-key")
try:
response = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": "Hello!"}]
)
except AuthenticationError as e:
print(f"Authentication failed: {e.message}")
print("Please check your API key")
except RateLimitError as e:
print(f"Rate limit exceeded: {e.message}")
print("Please try again later")
except InternalServerError as e:
print(f"Server error: {e.message}")
print("Please contact support if this persists")
HTTP status code errors
400 Bad Request
from dedalus_labs import Dedalus, BadRequestError
client = Dedalus(api_key="your-api-key")
try:
response = client.chat.completions.create(
model="invalid-model",
messages=[{"role": "user", "content": "Hello"}]
)
except BadRequestError as e:
print(f"Invalid request: {e.message}")
print(f"Error code: {e.code}")
print(f"Error type: {e.type}")
print(f"Parameter: {e.param}")
401 Authentication Error
from dedalus_labs import Dedalus, AuthenticationError
try:
client = Dedalus(api_key="invalid-key")
response = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": "Hello"}]
)
except AuthenticationError as e:
print("Invalid API key or authentication failed")
print(f"Details: {e.message}")
# Re-authenticate or prompt user for valid credentials
403 Permission Denied
from dedalus_labs import Dedalus, PermissionDeniedError
client = Dedalus(api_key="your-api-key")
try:
response = client.chat.completions.create(
model="restricted-model",
messages=[{"role": "user", "content": "Hello"}]
)
except PermissionDeniedError as e:
print(f"Access denied: {e.message}")
print("You may not have access to this resource")
404 Not Found
from dedalus_labs import Dedalus, NotFoundError
client = Dedalus(api_key="your-api-key")
try:
response = client.chat.completions.create(
model="non-existent-model",
messages=[{"role": "user", "content": "Hello"}]
)
except NotFoundError as e:
print(f"Resource not found: {e.message}")
print("The model or endpoint may not exist")
422 Unprocessable Entity
from dedalus_labs import Dedalus, UnprocessableEntityError
client = Dedalus(api_key="your-api-key")
try:
response = client.chat.completions.create(
model="gpt-4",
messages=[], # Empty messages
max_tokens=-1 # Invalid parameter
)
except UnprocessableEntityError as e:
print(f"Validation error: {e.message}")
print(f"Parameter: {e.param}")
print(f"Error body: {e.body}")
429 Rate Limit Error
import time
from dedalus_labs import Dedalus, RateLimitError
client = Dedalus(api_key="your-api-key")
max_retries = 3
for attempt in range(max_retries):
try:
response = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": "Hello"}]
)
break
except RateLimitError as e:
if attempt < max_retries - 1:
wait_time = 2 ** attempt # Exponential backoff
print(f"Rate limited. Waiting {wait_time}s...")
time.sleep(wait_time)
else:
print(f"Rate limit exceeded after {max_retries} attempts")
raise
The SDK automatically retries rate limit errors with exponential backoff up to
max_retries (default: 2). You can configure this when creating the client.500 Internal Server Error
from dedalus_labs import Dedalus, InternalServerError
client = Dedalus(api_key="your-api-key")
try:
response = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": "Hello"}]
)
except InternalServerError as e:
print(f"Server error: {e.message}")
print(f"Status code: {e.status_code}")
print(f"Request ID: {e.request_id}")
print("Please contact support with the request ID")
Network and connection errors
Timeout errors
import httpx
from dedalus_labs import Dedalus, APITimeoutError
client = Dedalus(
api_key="your-api-key",
timeout=httpx.Timeout(timeout=10.0, connect=5.0)
)
try:
response = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": "Hello"}]
)
except APITimeoutError as e:
print("Request timed out")
print(f"Details: {e.message}")
# Retry with longer timeout or handle gracefully
Connection errors
from dedalus_labs import Dedalus, APIConnectionError
client = Dedalus(api_key="your-api-key")
try:
response = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": "Hello"}]
)
except APIConnectionError as e:
print("Connection failed")
print(f"Details: {e.message}")
print("Check your network connection")
Validation errors
Response validation errors
from dedalus_labs import Dedalus, APIResponseValidationError
client = Dedalus(
api_key="your-api-key",
_strict_response_validation=True
)
try:
response = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": "Hello"}]
)
except APIResponseValidationError as e:
print("Invalid response format from API")
print(f"Status code: {e.status_code}")
print(f"Response body: {e.body}")
Streaming-specific errors
Length finish reason error
from dedalus_labs import Dedalus
from dedalus_labs._exceptions import LengthFinishReasonError
from pydantic import BaseModel
class Response(BaseModel):
answer: str
client = Dedalus(api_key="your-api-key")
try:
with client.chat.completions.stream(
model="gpt-4",
messages=[{"role": "user", "content": "Explain quantum physics"}],
response_format=Response,
max_tokens=10 # Too low for structured output
) as stream:
for _ in stream:
pass
except LengthFinishReasonError as e:
print("Response truncated due to token limit")
print(f"Completion: {e.completion}")
if e.completion.usage:
print(f"Tokens used: {e.completion.usage.total_tokens}")
Content filter error
from dedalus_labs import Dedalus
from dedalus_labs._exceptions import ContentFilterFinishReasonError
client = Dedalus(api_key="your-api-key")
try:
response = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": "Inappropriate content"}]
)
except ContentFilterFinishReasonError as e:
print("Request rejected by content filter")
print(f"Details: {e}")
Accessing error details
AllAPIError exceptions provide detailed information:
from dedalus_labs import Dedalus, APIStatusError
client = Dedalus(api_key="your-api-key")
try:
response = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": "Hello"}]
)
except APIStatusError as e:
# HTTP response details
print(f"Status code: {e.status_code}") # e.g., 400, 401, 500
# Error message
print(f"Message: {e.message}")
# Request ID for support
print(f"Request ID: {e.request_id}")
# Error code (if provided)
print(f"Error code: {e.code}")
# Error type (if provided)
print(f"Error type: {e.type}")
# Parameter that caused the error
print(f"Parameter: {e.param}")
# Full response body
print(f"Body: {e.body}")
# Original HTTP response
print(f"Response: {e.response}")
# Original HTTP request
print(f"Request: {e.request}")
Complete error handling example
import time
import httpx
from dedalus_labs import (
Dedalus,
APIError,
AuthenticationError,
RateLimitError,
APITimeoutError,
APIConnectionError,
InternalServerError,
)
def chat_with_retry(
client: Dedalus,
message: str,
max_retries: int = 3
) -> str | None:
"""Send a chat message with comprehensive error handling."""
for attempt in range(max_retries):
try:
response = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": message}]
)
return response.choices[0].message.content
except AuthenticationError as e:
print(f"Authentication failed: {e.message}")
print("Please check your API key")
return None # Don't retry auth errors
except RateLimitError as e:
if attempt < max_retries - 1:
wait_time = 2 ** attempt
print(f"Rate limited. Retrying in {wait_time}s...")
time.sleep(wait_time)
else:
print("Rate limit exceeded after max retries")
return None
except APITimeoutError as e:
if attempt < max_retries - 1:
print(f"Request timed out. Retrying...")
else:
print("Request timed out after max retries")
return None
except APIConnectionError as e:
if attempt < max_retries - 1:
wait_time = 1
print(f"Connection failed. Retrying in {wait_time}s...")
time.sleep(wait_time)
else:
print("Connection failed after max retries")
return None
except InternalServerError as e:
if attempt < max_retries - 1:
wait_time = 2 ** attempt
print(f"Server error. Retrying in {wait_time}s...")
print(f"Request ID: {e.request_id}")
time.sleep(wait_time)
else:
print("Server error after max retries")
print(f"Request ID: {e.request_id}")
return None
except APIError as e:
# Catch-all for other API errors
print(f"API error: {e.message}")
print(f"Status: {e.status_code}")
return None
return None
if __name__ == "__main__":
client = Dedalus(
api_key="your-api-key",
timeout=httpx.Timeout(timeout=30.0, connect=5.0),
max_retries=2
)
result = chat_with_retry(client, "Hello, how are you?")
if result:
print(f"Response: {result}")
else:
print("Failed to get response")
Best practices
Always handle authentication errors - These indicate invalid API keys and should not be retried without user intervention.
Implement exponential backoff for rate limits - The SDK does this automatically, but you may need additional logic for your use case.
Log request IDs - When errors occur, log the
request_id to help with debugging and support requests.Don’t catch
DedalusError or APIError without re-raising or handling specific subtypes. This can mask important errors.