You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
refactor(errors): collapse per-exception reconstruct/reduce boilerplate with _KeywordReduceMixin
Replace six hand-repeated _reconstruct_X functions and __reduce__ methods
with a single _KeywordReduceMixin that pickles via self.__dict__. Updates
architecture/errors.md with the pickling invariant. Pure refactor, no
behavior change; all 775 tests pass with 100% coverage.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: architecture/errors.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -18,6 +18,8 @@ The error-mapping table (what `httpx2` exception maps to which `httpware` except
18
18
19
19
The "no `__init__` override" rule scopes only to `StatusError` subclasses. Non-status `ClientError` subclasses — `DecodeError`, `MissingDecoderError`, `BulkheadFullError`, `RetryBudgetExhaustedError`, `CircuitOpenError`, `ResponseTooLargeError` — deliberately define `__init__` with keyword-only fields.
20
20
21
+
These six non-status `ClientError` subclasses inherit `__reduce__` from `_KeywordReduceMixin`, which pickles via `self.__dict__`. This requires `self.__dict__` to exactly mirror the `__init__` keyword parameters — do not store any additional derived attribute on these classes without also updating `__init__`'s parameters, or pickling will silently drop it.
22
+
21
23
`ResponseTooLargeError` is raised when `max_response_body_bytes` is set and a response body would exceed the cap — status-agnostic (a `200` can trip it), counting **decoded** bytes. It fires from the non-streaming terminal (`send()`) and from `stream()`'s internal error pre-read; user-driven `stream()` iteration is never capped. The `reason` field discriminates the two trip modes: `"declared"` (the declared `Content-Length` already exceeds the cap, rejected before any byte is read — `content_length` holds it) and `"streamed"` (the decoded body crossed the cap mid-read, the chunked or compression-bomb case, where the true size is unknown by design). It is a non-status `ClientError`; it does not carry a `StatusError`-style positional `response` and is not in `STATUS_TO_EXCEPTION`. Because it is neither a `StatusError`, `NetworkError`, nor `TimeoutError`, it is not retried and does not count toward the circuit breaker.
22
24
23
25
## Security: request headers are reachable via `exc.response.request`
0 commit comments