Error Handling¶
Exception Hierarchy¶
SiloError Base for all SDK errors
├── AuthenticationError Token rejected by the API
│ └── InvalidTokenError Specific: token format or value invalid
├── ConfigurationError Missing or invalid config (before any network call)
├── ValidationError Invalid parameter values
├── RateLimitError Too many requests
├── BrowsingAPIError BrowsingAPI-specific errors
│ └── ContextNotFoundError Context ID doesn't exist
├── UserManagementAPIError UserManagementAPI-specific errors
│ └── UserNotFoundError Username doesn't exist
├── OrgManagementAPIError OrgManagementAPI-specific errors
│ └── OrgNotFoundError Org slug doesn't exist
├── FileAPIError FileAPI-specific errors
│ └── FileNotFoundError File ID doesn't exist (shadows builtins.FileNotFoundError)
├── LogExtractionAPIError LogExtractionAPI-specific errors
├── HarvesterAPIError HarvesterAPI-specific errors
│ └── TaskNotFoundError Task ID doesn't exist
├── InsufficientPermissionsError Token lacks required scope
└── QuotaExceededError Org quota limit hit
Basic Exception Handling¶
Import from the top-level module
All exceptions can be imported from silo_sdk for convenience:
Always catch the most specific exception first:
from silo_sdk import (
BrowsingAPI,
BrowsingAPIError,
ContextNotFoundError,
AuthenticationError,
ConfigurationError,
ValidationError,
)
try:
browsing = BrowsingAPI(config)
info = browsing.get_context("some_context_id")
except ContextNotFoundError:
print("Context does not exist or has already been deleted")
except AuthenticationError as e:
print(f"Token rejected: {e}")
except BrowsingAPIError as e:
print(f"API error: {e}")
if e.status_code:
print(f" HTTP {e.status_code}")
except ConfigurationError as e:
print(f"Configuration problem: {e}")
Exception Attributes¶
All SiloError subclasses carry these attributes:
| Attribute | Type | Description |
|---|---|---|
message |
str |
Human-readable error description |
status_code |
int \| None |
HTTP status code (if applicable) |
response_data |
dict \| None |
Raw API response body (if available) |
request_id |
str \| None |
Request ID for support escalation |
except BrowsingAPIError as e:
print(f"Error: {e.message}")
print(f"Status: {e.status_code}")
print(f"Request ID: {e.request_id}") # include in support tickets
Common Error Scenarios¶
| Scenario | Exception | Resolution |
|---|---|---|
| Token not in config | ConfigurationError |
Add token to .env or config file |
| Token expired/invalid | InvalidTokenError |
Rotate the token |
| Wrong token for API module | InsufficientPermissionsError |
Use the correct token type |
| Invalid parameter values | ValidationError |
Check method parameter docs |
| Resource already deleted | ContextNotFoundError, UserNotFoundError, etc. |
Check resource existence first |
| Org quota hit | QuotaExceededError |
Contact your Authentic8 admin |
Error Handling in Flows¶
For multi-step flows (create → use → cleanup), handle errors at each step and ensure cleanup runs:
context_id = None
try:
context_id = browsing.create_context(url="https://example.com", username="user@org.com")
# ... do something with the context ...
except BrowsingAPIError as e:
print(f"Operation failed: {e}")
finally:
if context_id:
try:
browsing.delete_context(context_id)
except ContextNotFoundError:
pass # already gone