Error handling

Backends translate their library’s exceptions into one family, so calling code never depends on the HTTP library:

  • ClientError — everything below

  • TransportError — no usable HTTP response (DNS, connect, TLS, connection lost); the original library exception stays chained as __cause__

  • TimeoutError — a TransportError that is also the built-in TimeoutError

  • APIError — an HTTP response arrived but was unusable (unexpected status, malformed payload); carries .request and .response

from action0.client import APIError
from action0.client import TransportError

try:
    item = client.send(GetItem(item_id=42))
except TransportError as error:
    ...  # network trouble — retry, circuit-break, ...
except APIError as error:
    ...  # the API answered, but not with what we expected

With async and Twisted backends the same errors arrive at await time / in the errback instead of being raised synchronously.