The Wrenn SDK maps every HTTP error response to a typed Python exception. Instead of inspecting raw status codes, you catch the specific exception class that matches the failure — or catch the base WrennError to handle all API errors in one place.
Base class
All SDK exceptions inherit from WrennError. Every instance exposes three attributes:
| Attribute | Type | Description |
|---|
.code | str | Machine-readable error code from the API (e.g. "not_found") |
.message | str | Human-readable description of what went wrong |
.status_code | int | HTTP status code of the response |
Error reference
| Exception | HTTP Status | Error Code | When it occurs |
|---|
WrennValidationError | 400 | invalid_request | Bad or missing request parameters |
WrennAuthenticationError | 401 | unauthorized | Invalid or missing API key |
WrennForbiddenError | 403 | forbidden | Authenticated but not authorized for this resource |
WrennNotFoundError | 404 | not_found | The requested resource does not exist |
WrennConflictError | 409 | invalid_state, conflict | Resource is in a state that prevents the operation |
WrennHostHasCapsulesError | 409 | host_has_capsules | Host still has running capsules and cannot be removed |
WrennHostUnavailableError | 503 | host_unavailable | No suitable host is available to fulfill the request |
WrennAgentError | 502 | agent_error | The host agent returned an error |
WrennInternalError | 500 | internal_error | Unexpected server-side error |
WrennHostHasCapsulesError
WrennHostHasCapsulesError is a subclass of WrennConflictError and adds one extra attribute:
| Attribute | Type | Description |
|---|
.capsule_ids | list[str] | IDs of the capsules still running on the host |
Use .capsule_ids to destroy or pause the blocking capsules before retrying.
Catching errors
Catch all API errors
Use WrennError as a catch-all when you want to handle any API failure uniformly:
from wrenn import WrennError
try:
result = capsule.commands.run("python script.py")
except WrennError as e:
print(f"API error {e.status_code} [{e.code}]: {e.message}")
Catch specific errors
Import and catch the typed exception you expect:
from wrenn import Capsule, WrennNotFoundError
try:
capsule = Capsule.connect("cl-abc123")
except WrennNotFoundError:
print("That capsule no longer exists.")
Handle multiple error types
You can match multiple exception types in a single try block:
from wrenn import (
WrennError,
WrennAuthenticationError,
WrennNotFoundError,
WrennHostHasCapsulesError,
WrennValidationError,
)
try:
capsule.commands.run("./deploy.sh")
except WrennAuthenticationError:
print("Check your WRENN_API_KEY — the request was not authenticated.")
except WrennNotFoundError:
print("Capsule not found. It may have been destroyed.")
except WrennHostHasCapsulesError as e:
print(f"Host is still running capsules: {e.capsule_ids}")
except WrennValidationError as e:
print(f"Bad request: {e.message}")
except WrennError as e:
# Fallback for any other API error
print(f"Unexpected error [{e.code}]: {e.message}")
Always place more specific exception types before the base WrennError catch. Python evaluates except clauses in order, so a broad catch placed first will swallow the typed ones below it.
Importing exceptions
All exception classes are importable directly from the wrenn package:
from wrenn import (
WrennError,
WrennValidationError,
WrennAuthenticationError,
WrennForbiddenError,
WrennNotFoundError,
WrennConflictError,
WrennHostHasCapsulesError,
WrennHostUnavailableError,
WrennAgentError,
WrennInternalError,
)