Python SDK · Errors

The recorder package exports five error classes:

  • HTTPError. Non-2xx from the ingestion endpoint. Check status_code, body, retry_after (the server's Retry-After in seconds, 0.0 if absent or not a whole number of seconds), and transient() (true for 5xx and 429). A transport that raises urllib.error.HTTPError surfaces as this error too.
  • NetworkError. The request failed before any response arrived (connection refused, reset, socket timeout, or another OSError or http.client.HTTPException). The original exception is on __cause__. Always transient. It subclasses OSError.
  • EncodeError. An event could not be serialized: a wrongly typed field, or a value JSON can't encode. The original error is on __cause__. Nothing is sent. It subclasses both TypeError and ValueError.
  • BufferFullError. Overflow when overflow="error".
  • DrainTimeoutError. close() exceeded drain_timeout with pending events.

The buffered recorder handles the first three itself: HTTPError with transient() and NetworkError are retried, and a batch failing with a 400, 409, 413 or EncodeError is split to isolate the bad event. See What happens when delivery fails. They reach your code only when you use HTTPRecorder directly, or as the err passed to on_drop:

from everscribe.recorder import HTTPError, HTTPRecorder, NetworkError

http_rec = HTTPRecorder(project_id, api_key)
try:
    http_rec.record(e)
except HTTPError as err:
    if err.transient():
        wait = err.retry_after or 1.0  # 0.0 means the server sent no Retry-After
        ...  # 5xx or 429: safe to retry after `wait` seconds
except NetworkError:
    ...  # no response: safe to retry with the same event id

A custom inner recorder opts into retries by raising an error with a truthy transient attribute or a transient() method that returns True. NetworkError and TimeoutError are retried too. A multi-event batch failing with EncodeError or an HTTPError 400, 409 or 413 is split first. Errors that are not retried or split drop the batch as REJECTED; an inner recorder without record_batch drops only the event that failed.

Minter calls raise a plain ValueError on client-side validation failures (invalid tenant_id, malformed wildcard, out-of-range expires_in) before any HTTP call is made, MinterError (with status_code / body) on HTTP 400/401/404, or a transport error (urllib.error.URLError, socket.timeout) on network failure.