-
Notifications
You must be signed in to change notification settings - Fork 5.2k
fix(streaming): wrap mid-stream transport errors as APITimeoutError/APIConnectionError #3818
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,7 +11,8 @@ | |
| import httpx2 | ||
|
|
||
| from ._utils import is_mapping, extract_type_var_from_base | ||
| from ._exceptions import APIError | ||
| from ._httpx2 import timeout_exceptions | ||
| from ._exceptions import APIError, OpenAIError, APITimeoutError, APIConnectionError | ||
|
|
||
| if TYPE_CHECKING: | ||
| from ._client import OpenAI, AsyncOpenAI | ||
|
|
@@ -106,6 +107,12 @@ def __stream__(self) -> Iterator[_T]: | |
| cast_to=cast_to, | ||
| response=response, | ||
| ) | ||
| except timeout_exceptions() as err: | ||
| raise APITimeoutError(request=response.request) from err | ||
| except OpenAIError: | ||
| raise | ||
| except Exception as err: | ||
| raise APIConnectionError(request=response.request) from err | ||
|
Comment on lines
+114
to
+115
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This catch also converts exceptions unrelated to the connection into Useful? React with 👍 / 👎. |
||
| finally: | ||
| # Ensure the response is closed even if the consumer doesn't read all data | ||
| response.close() | ||
|
|
@@ -216,6 +223,12 @@ async def __stream__(self) -> AsyncIterator[_T]: | |
| cast_to=cast_to, | ||
| response=response, | ||
| ) | ||
| except timeout_exceptions() as err: | ||
| raise APITimeoutError(request=response.request) from err | ||
| except OpenAIError: | ||
| raise | ||
| except Exception as err: | ||
| raise APIConnectionError(request=response.request) from err | ||
| finally: | ||
| # Ensure the response is closed even if the consumer doesn't read all data | ||
| await response.aclose() | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When an Assistants stream raises
httpx2.ReadTimeout, this conversion meansAssistantEventHandler.__stream__and its async counterpart no longer match their_timeout_exceptions()branches, so they invoke onlyon_exception()and skipon_timeout(). This also changes the exception exposed byuntil_done()and breaks the existing sync and async callback expectations intests/test_httpx2.py::test_assistant_stream_timeout_callbacks_preserve_httpx2_family; recognizeAPITimeoutErrorin those handlers (or preserve the transport exception for that path).Useful? React with 👍 / 👎.