Skip to main content
The Python SDK provides a structured error hierarchy and two error handling patterns: exceptions (default) and safe results. Every method that can fail has a safe_* variant that returns a result object instead of raising. This page covers how to catch and handle errors in the SDK. For the full list of ERR-xxxx error codes returned by the API, see the Error Codes Reference.

Error Hierarchy

All SDK exceptions inherit from PhalaCloudError:

Catching Errors

Basic Exception Handling

Order matters when catching exceptions. Catch more specific subclasses first — ResourceError before BusinessError, and BusinessError before ApiError.

Error Classes

PhalaCloudError

Base class for all SDK exceptions. Catches everything.

RequestError

Raised when the HTTP request itself fails (DNS resolution, connection timeout, TLS errors). This wraps httpx.HTTPError.

ApiError

Base class for all HTTP error responses from the API.

AuthError

Raised on HTTP 401 or 403. Usually means the API key is invalid or expired.

BusinessError

Raised on HTTP 400, 409, and other 4xx client errors that are not auth-related.

ConflictError

Subclass of BusinessError. Raised on HTTP 409 when there is no structured error code. These conflicts are typically transient — for example, another operation is already in progress on the same CVM. Retrying after a short delay often resolves the issue.

ResourceError

Subclass of BusinessError. Raised when the API returns a structured error with an error_code field. These are deterministic business errors with additional context.

ServerError

Raised on HTTP 500+. Indicates a problem on the Phala Cloud side.

ValidationError

Raised when a response passes HTTP validation but fails Pydantic model validation. This is rare and usually indicates an API response format change.

Safe Methods

Every action method has a safe_* counterpart that wraps the result in a SafeResult dataclass instead of raising exceptions.

SafeResult

The unwrap() method gives you a quick escape hatch when you want safe handling in most cases but still want to raise in unexpected situations:
Safe methods catch PhalaCloudError and Pydantic ValidationError. Other exceptions (like KeyboardInterrupt) still propagate normally.

Async Safe Methods

The async client works identically:

Error Codes

The phala_cloud.error_codes module provides constants for all structured error codes. Use these to match specific errors in your error handling logic.

Available Error Code Modules

Practical Patterns

Retry on Conflict

ConflictError (409 without structured code) is often transient. A simple retry loop handles it:

Combining Safe + Exception Handling

Use safe methods for expected failures and exceptions for unexpected ones: