Errors and exceptions
The SDK exception hierarchy and how to handle the most common failures.
Every SDK failure raises a subclass of vilvik.VilvikError. You can catch the base class to handle any SDK error in one place, or catch a specific subclass to branch on the kind of failure. The mapping to HTTP status codes mirrors Errors.
The hierarchy¶
VilvikError
โโโ TimeoutError
โโโ APIError
โโโ AuthenticationError (401, 403)
โโโ NotFoundError (404)
โโโ ValidationError (400, 422)
โโโ RateLimitError (429)
What each error means¶
| Exception | When it is raised |
|---|---|
VilvikError |
Base class. Catch this to handle any SDK error in a single block. |
TimeoutError |
A polling helper such as Results.wait_for exceeded its deadline before the run finished. |
APIError |
The API returned a non-2xx response that did not match a more specific subclass (typically 5xx server errors). |
AuthenticationError |
API key missing, revoked, expired, or under-scoped for the requested action. |
NotFoundError |
The resource does not exist or is not visible to this key. |
ValidationError |
The request body failed server-side validation. |
RateLimitError |
Too many requests for the key's rate limit window. |
Common attributes on APIError¶
| Attribute | Type | What it holds |
|---|---|---|
status_code |
int |
HTTP status returned by the server. |
code |
str |
Stable machine-readable code (for example "validation_failed"). |
message |
str |
Human-readable summary. |
request_id |
str |
The X-Request-Id echoed back by the API. Quote this in support requests. |
payload |
dict |
The full decoded JSON body, preserved for debugging. |
RateLimitError also exposes retry_after: the number of seconds the server advises you to wait before retrying. It is None when the server did not advise one.
Catching errors¶
Branch on the specific failure when you can:
import vilvik
try:
submission = client.submissions.create(fitness_func=src, num_genes=5)
except vilvik.ValidationError as exc:
print("Bad parameters:", exc.message, exc.payload)
except vilvik.AuthenticationError:
print("Your API key was rejected.")
except vilvik.RateLimitError as exc:
wait = exc.retry_after or 30
print(f"Rate-limited; retrying in {wait}s.")
except vilvik.APIError as exc:
print(f"API error {exc.status_code}: {exc.message} (request {exc.request_id})")
Or catch the base class when you want to log everything uniformly:
try:
submission = client.submissions.create(...)
except vilvik.VilvikError as exc:
logger.exception("vilvik call failed: %s", exc)
raise
Retries¶
The transport retries idempotent requests (GET, HEAD) on transient failures up to max_retries times. Write requests (POST, DELETE) are never retried automatically because they could create duplicates. If you want a write to be safely retryable, pass an idempotency_key (the SDK adds one for you by default on create and reexecute).