Python SDK — Error Handling

Exception hierarchy

ClassHTTP statusWhen raised
ApiErrorany non-2xxBase class for all HTTP failures; catch this to handle any API error
NotFoundError404Resource does not exist or is not visible to the caller
ConflictError409Request conflicts with the current state of a resource
UnprocessableEntityError422Request body failed server-side validation

Import paths:

1from onepin.core.api_error import ApiError
2from onepin.errors import NotFoundError, ConflictError, UnprocessableEntityError

All error classes expose:

AttributeTypeDescription
status_codeint | NoneHTTP status code
headersdict | NoneResponse headers
bodyAnyParsed response body

Catching errors

1import os
2from onepin import OnePinClient
3from onepin.core.api_error import ApiError
4from onepin.errors import NotFoundError, ConflictError, UnprocessableEntityError
5
6client = OnePinClient(token=os.environ["ONEPIN_API_KEY"])
7
8try:
9 result = client.workflows.get(workflow_id="3fa85f64-5717-4562-b3fc-2c963f66afa6")
10 wf = result.data
11except NotFoundError:
12 print("Workflow not found")
13except ConflictError as e:
14 print(f"Conflict ({e.status_code}): {e.body}")
15except UnprocessableEntityError as e:
16 print(f"Validation error: {e.body}")
17except ApiError as e:
18 print(f"API error {e.status_code}: {e.body}")

Retrying

The SDK does not retry automatically. For idempotent operations, retry on 5xx errors or network failures with exponential backoff. Check e.status_code to distinguish server errors from client errors, and inspect e.headers for a Retry-After value on rate-limit responses:

1import time
2from onepin.core.api_error import ApiError
3
4for attempt in range(3):
5 try:
6 result = client.workflows.get(workflow_id=workflow_id)
7 wf = result.data
8 break
9 except ApiError as e:
10 if e.status_code is not None and e.status_code >= 500:
11 if attempt == 2:
12 raise
13 # Honour Retry-After header if present, otherwise use backoff
14 ra_header = (e.headers or {}).get("Retry-After")
15 wait = float(ra_header) if ra_header else 2 ** attempt
16 time.sleep(wait)
17 else:
18 raise # 4xx errors are not retryable