Error Handling
The SDK provides typed exceptions for different error scenarios.
Exception Hierarchy
Section titled “Exception Hierarchy”QualiaError├── AuthenticationError└── QualiaAPIError ├── NotFoundError ├── ValidationError └── RateLimitErrorfrom qualia import ( Qualia, QualiaError, QualiaAPIError, AuthenticationError, NotFoundError, ValidationError, RateLimitError,)
try: client = Qualia(api_key="invalid-key") client.models.types()except AuthenticationError as e: print(f"Auth failed: {e}")except NotFoundError as e: print(f"Not found: {e}")except ValidationError as e: print(f"Validation error: {e}")except RateLimitError as e: print(f"Rate limited. Retry after: {e.retry_after}s")except QualiaAPIError as e: print(f"API error [{e.status_code}]: {e.message}")except QualiaError as e: print(f"SDK error: {e}")Exception Details
Section titled “Exception Details”| Exception | Raised for |
|---|---|
QualiaError | Base exception for all SDK errors; also a request that got no answer (timeout, network) |
QualiaAPIError | Any other error status; carries status_code, message and code |
AuthenticationError | 401 or 403: an invalid or missing API key, or one without access |
NotFoundError | 404: the resource doesn’t exist |
ValidationError | 400 or 422: invalid request parameters; errors holds the per-field list on a 422 |
RateLimitError | 429: too many requests; retry_after is the server’s Retry-After in seconds |
Retries
Section titled “Retries”A 429 on a GET, HEAD, OPTIONS, PUT or DELETE is sent again after its
Retry-After (at least 1 second; 1, 2 and 4 seconds without one), up to three
times while the server asks for at most 60 seconds; only then is
RateLimitError raised. A POST or PATCH that gets a 429 is never sent
again: the error is raised at once, so your code decides whether repeating it
is safe.
The long waits, client.checks.wait and client.task_drafts.wait (and the
CLI’s --wait on them), sit out up to five failed reads in a row (any 5xx, a
408, a timeout or a dropped connection), backing off between them. Any other
4xx ends the wait at once, a 429 included: its request was already retried as
above, never past the wait’s timeout. Neither stops the run, which keeps going server-side.