WarmHubError
Class: warmhub.WarmHubError
WarmHubError(code: str, message: str, status: int | None = None, hint: str | None = None, retry_after: float | None = None, error_code: str | None = None, details: ErrorDetails | Mapping[str, Any] | None = None)Normalized error for transport, tRPC, validation, and backend failures.
isinstance(err, WarmHubError) is the exact Python analogue of
TypeScript’s isWarmHubError(err).
Cause. Raised when a request fails: a transport error, a tRPC error
envelope, a validation rejection, or a backend fault. kind says which.
Retryability. Depends on kind, so do not assume. Call
is_retryable; it is True for NETWORK, CANCELLED, BACKEND, and
RATE_LIMITED and False for VALIDATION_ERROR and NOT_FOUND, which no retry
can fix.
Corrective action. For a retryable kind, wait retry_after seconds and
retry. For a conflict, use is_conflict, re-read, and reapply with the
current version. Otherwise fix the request the message names.
Properties and attributes
Section titled “Properties and attributes”name = 'WarmHubError'Mirrors TypeScript’s this.name = 'WarmHubError'. to_warmhub_error
reads it to recognize an error raised by a different copy of the SDK,
where an isinstance check fails.
submission_id
Section titled “submission_id”submission_id = NoneThe submission this chunk belonged to.
event_request_id
Section titled “event_request_id”event_request_id = NoneThe chunk’s deterministic event-request identity.
chunk_ordinal
Section titled “chunk_ordinal”chunk_ordinal = NoneThe chunk’s zero-based position in the submission.
code = codeStable SDK error code or pass-through backend domain code.
message
Section titled “message”message = messageDocumentation is not yet available.
status
Section titled “status”status = statusHTTP status from the failing response, when one was available.
hint = hintOptional human-readable hint surfaced by the backend.
retry_after
Section titled “retry_after”retry_after = None if retry_after is None else min(max(retry_after, 0.0), MAX_RETRY_AFTER_SECONDS)Seconds to wait before retrying. Present on RATE_LIMITED.
Clamped to MAX_RETRY_AFTER_SECONDS HERE rather than at the
one construction site that reads a header. The value reaches this
class from four paths — header, REST body, tRPC envelope, and
re-normalization — and capping one of them left the stated invariant
(“one hostile response must not put the client to sleep for a week”)
true only of the path that happened to be written last.
error_code
Section titled “error_code”error_code = error_codeCanonical domain code from the response body. Set iff the backend
wire carried a structured error.code.
details
Section titled “details”details = decode_error_details(details) if isinstance(details, Mapping) else detailsDocumentation is not yet available.
kindAlias for code, matching TypeScript’s get kind().
expected_version
Section titled “expected_version”expected_versionThe version the caller asserted, on a lost optimistic-concurrency
race. None unless details.reason is
"expected_version_mismatch" — pair with current_version.
current_version
Section titled “current_version”current_versionThe version the server actually holds. Re-read at this version and
retry; see expected_version.
lease_expires_at
Section titled “lease_expires_at”lease_expires_atISO-8601 instant the blocking read lease expires, or None.
validation_issues
Section titled “validation_issues”validation_issuesPer-field validation issues. Empty, not None, when the wire
carried a different reason — a caller iterating this needs no guard,
and an empty loop body is the correct behavior for “no issues
reported”.
reset_at
Section titled “reset_at”reset_atISO-8601 instant a rate limit lifts, or None.
Distinct from retry_after, which is the transport-level
relative delay and is populated from the response envelope rather than
from details. When the backend sends structured
rate_limit_reset details, both are present and they agree; when it
sends only one, the other stays None.
backend_code
Section titled “backend_code”backend_codeDeprecated alias for error_code.
Retained because TypeScript still exposes backendCode during the
GH-3533 migration window; dropping it would be a silent surface
difference between the clients.