The SDK uses a structured exception hierarchy. All exceptions inherit from InfiniumError.
Exception Hierarchy
InfiniumError
├── AuthenticationError (401)
├── ValidationError (422)
├── RateLimitError (429)
├── NetworkError (connection failures)
├── InfiniumTimeoutError (request timeouts)
├── ServerError (500+)
├── NotFoundError (404)
├── BatchError (batch operation failures)
└── ConfigurationError (invalid client config)
Catching Errors
from infinium.exceptions import (
InfiniumError,
AuthenticationError,
RateLimitError,
ValidationError,
NetworkError,
ServerError,
InfiniumTimeoutError,
NotFoundError,
)
try:
client.send_task_data(task_data)
except AuthenticationError:
# Bad agent_id or agent_secret
print("Check your credentials")
except ValidationError as e:
# Invalid input data
print(f"Field '{e.field}': {e.message}")
except RateLimitError as e:
# Too many requests
print(f"Retry after {e.retry_after} seconds")
except NotFoundError as e:
# Agent or resource not found
print(f"{e.resource_type} '{e.resource_id}' not found")
except NetworkError as e:
# Cannot reach the API
print(f"Network error: {e.original_error}")
except InfiniumTimeoutError as e:
# Request timed out
print(f"Timed out after {e.timeout_duration}s")
except ServerError:
# 5xx from the API (after retries exhausted)
print("Server error -- try again later")
except InfiniumError:
# Catch-all for any SDK error
print("Something went wrong")
Exception Details
All exceptions have these base attributes:
| Attribute | Type | Description |
|---|---|---|
message | str | Human-readable error message |
status_code | int or None | HTTP status code (if applicable) |
details | dict or None | Additional context |
AuthenticationError
Raised on HTTP 401. Default message: "Authentication failed".
ValidationError
Raised for invalid input data (client-side validation or HTTP 422).
| Attribute | Type | Description |
|---|---|---|
field | str or None | Which field failed validation |
RateLimitError
Raised on HTTP 429.
| Attribute | Type | Description |
|---|---|---|
retry_after | int or None | Seconds to wait before retrying |
NetworkError
Raised when the API is unreachable (DNS failure, connection refused, etc.).
| Attribute | Type | Description |
|---|---|---|
original_error | Exception or None | The underlying network exception |
InfiniumTimeoutError
Raised when a request exceeds the configured timeout.
| Attribute | Type | Description |
|---|---|---|
timeout_duration | float or None | The timeout threshold in seconds |
Also available as TimeoutError (alias) for convenience.
ServerError
Raised on HTTP 5xx after all retries are exhausted. Default status code: 500.
NotFoundError
Raised on HTTP 404.
| Attribute | Type | Description |
|---|---|---|
resource_type | str or None | Type of resource (e.g., "agent", "trace") |
resource_id | str or None | ID of the missing resource |
BatchError
Raised when a batch operation fails.
| Attribute | Type | Description |
|---|---|---|
successful_count | int | Number of successful sends |
failed_count | int | Number of failed sends |
errors | list | Error messages |
ConfigurationError
Raised for invalid client configuration.
| Attribute | Type | Description |
|---|---|---|
config_key | str or None | Which config key is invalid |
Retry Behavior
The SDK automatically retries certain errors with exponential backoff:
| Error Type | Auto-Retried? |
|---|---|
ServerError (5xx) | Yes |
NetworkError | Yes |
InfiniumTimeoutError | Yes |
AuthenticationError (401) | No |
ValidationError (422) | No |
RateLimitError (429) | No |
NotFoundError (404) | No |
Retry Configuration
client = InfiniumClient(
agent_id="...",
agent_secret="...",
max_retries=3, # Number of retry attempts (default: 3)
timeout=30.0, # Per-request timeout in seconds (default: 30)
)
Backoff is exponential with jitter: min(base_delay * 2^attempt + random_jitter, max_delay).
Rate Limiting
The SDK includes a built-in token bucket rate limiter:
client = InfiniumClient(
agent_id="...",
agent_secret="...",
enable_rate_limiting=True, # Enabled by default
requests_per_second=10.0, # Default: 10 req/s
)
When enabled, the client automatically throttles requests to stay within the limit. This is both thread-safe (sync) and async-safe.
If the server returns a 429, a RateLimitError is raised with the retry_after hint — this is not auto-retried.
Validation
The SDK validates data before sending to catch errors early:
| Validation | Limit |
|---|---|
name length | Max 500 characters |
description length | Max 10,000 characters |
| String fields | Max 2,000 characters |
| Payload size | Max 1 MB |
| Duration | 0 to 86,400 seconds (24 hours) |
| Path IDs (agent_id, etc.) | Must be valid UUID format |
Validation failures raise ValidationError with the offending field name.