Repository navigation
fix(streaming): wrap mid-stream transport errors as APIError subclasses - #1974
intertermux-code wants to merge 2 commits into
Conversation
_streaming.py iterated the response with no error handling, so a read timeout or dropped connection mid-stream escaped as a raw httpx2 exception. Translate it the same way the initial send does: httpx2.TimeoutException -> APITimeoutError, other transport errors -> APIConnectionError, leaving SDK-originated errors untouched. Fixes anthropics#1919.
|
Two things look worth resolving before this lands. First, this is the same open issue already covered by #1920 and #1922. #1919 itself points to both of them, and both are still open. #1920 in particular changes these same two Second, this head is broader than those earlier fixes: except Exception as err:
if isinstance(err, AnthropicError):
raise
raise APIConnectionError(...)That Could the second handler be narrowed to |
…rrors The broad `except Exception` in `_iter_events` also caught decoder failures, so e.g. a `UnicodeDecodeError` from a malformed SSE line (or an exception from a custom SSEBytesDecoder) was relabeled as `APIConnectionError`. Scope the non-timeout handler to `httpx2.TransportError` so decoder errors keep their original identity, and add a regression test for it.
|
Done — narrowed both Also added On the duplication point: noted. #1920 has been untouched for a month, so I'll keep this branch live as the active one — happy to consolidate onto #1920 instead if you'd rather. |
Fixes #1919.
The initial send wraps transport failures (
httpx2.TimeoutException→APITimeoutError, other transport errors →APIConnectionError), but once the response was streaming,_streaming.pyiterated it with no handling — a read timeout or dropped connection mid-stream surfaced as the raw httpx exception, outside theAPIErrorhierarchy and outsidemax_retries.Stream._iter_eventsandAsyncStream._iter_eventsnow apply the same translation as the initial send, with the same passthrough for SDK-originated errors. Added sync/async regression tests using a mock transport that dies mid-stream.