Skip to main content
The SDK raises typed exceptions for API failures, validation issues, and network problems. The taxonomy mirrors the API’s ErrorResponse envelope, with subclasses per HTTP class for ergonomic catching.

Exception hierarchy

All classes are importable from devhelm:

DevhelmApiError

The most common error class — raised for any non-2xx HTTP response.

DevhelmValidationError

Raised before HTTP I/O when a request body fails Pydantic validation, and after a successful response when the response body doesn’t match the expected schema (rare — usually indicates a stale SDK).

DevhelmTransportError

Wraps httpx network failures (connection refused, DNS, TLS handshake, timeout) so callers don’t need to import httpx. The original exception is on __cause__.

Handling patterns

Catch by HTTP class

Retry on rate limits and 5xx

Don’t retry on DevhelmValidationError, DevhelmAuthError, DevhelmNotFoundError, or DevhelmConflictError — these are deterministic and won’t change without code or config changes.

Deploy lock contention

Catch-all logging

Wait timeouts

client.inboxes.wait, inbox.wait, client.email.wait, and address.wait hold the request open until a match arrives. These are the errors they and the other testing calls raise:
  • There is no timeout subclass. A 408 is a plain DevhelmApiError, so check code, and catch DevhelmRateLimitError first.
  • The SDK does not retry. Retrying a wait is safe: wait does not consume, so the same received_after finds the same item.
  • The HTTP timeout is timeout_ms plus 10 seconds, so the 408 arrives first. Set your test runner’s timeout above timeout_ms.
A negative assertion spends one wait from the shared budget. Give it a timeout that covers your sender’s latency plus a few seconds of storage lag. See Wait for a webhook in a test and Limits, quotas, and errors.

Next steps

Client reference

Full method reference for all resources.

Error patterns

Common error scenarios across all surfaces.