问题 / Problem
证据 / Evidence:
src/globalrouter/_client.py:211-214 使用 self._client.send(..., stream=True) 获取流式响应;当 status_code >= 400 时直接调用 error_from_response(result)。
src/globalrouter/_client.py:233-236 的 async 路径也同样对 unread streaming response 调用 error_from_response(result)。
src/globalrouter/_errors.py:31-40 的 error_from_response 会调用 response.json() 和 response.text。对于未读取的 stream=True 响应,httpx 会抛出 ResponseNotRead,导致 SDK 没有抛出设计文档中承诺的 GlobalRouterError。
影响 / Impact:
- 当 chat stream 或 task events 在建立流时返回 4xx/5xx,用户可能看到
httpx.ResponseNotRead,而不是包含 status、code、message、request_id 的 GlobalRouterError。这会破坏调用方的统一错误处理,并让认证、限流、服务端错误更难定位。
建议方向 / Suggested fix:
- 在 sync
stream() 的错误分支中先 result.read(),再调用 error_from_response(result),最后关闭响应。
- 在 async
stream_async() 的错误分支中先 await result.aread(),再调用 error_from_response(result),最后 await result.aclose()。
- 为 sync 和 async streaming 非 2xx 响应各加一个测试。
验证方式 / Verification:
- 构造
httpx.Response(429, stream=httpx.ByteStream(...)) 或等价 mock transport,调用 client.chat.stream(...) / client.chat.stream_async(...),断言抛出 GlobalRouterError 且保留 429、message、router code 等字段,而不是 ResponseNotRead。
价值 / Value:
- 修复后流式接口在失败场景下与普通请求拥有一致错误语义,提升 SDK correctness、operator 可诊断性和用户对 streaming 功能的信任。
价值 / Value
修复该问题可以提升正确性、可靠性和用户信任,降低 unread error response in globalrouter.stream 带来的排障与运维成本。
Fixing this issue improves correctness, reliability, and user trust while reducing debugging and operational cost caused by unread error response in globalrouter.stream.
证据 / Evidence
File: src/globalrouter/_client.py
Line: 212
Severity / 严重级别: high
Summary / 摘要: unread error response in globalrouter.stream
问题 / Problem
证据 / Evidence:
src/globalrouter/_client.py:211-214使用self._client.send(..., stream=True)获取流式响应;当status_code >= 400时直接调用error_from_response(result)。src/globalrouter/_client.py:233-236的 async 路径也同样对 unread streaming response 调用error_from_response(result)。src/globalrouter/_errors.py:31-40的error_from_response会调用response.json()和response.text。对于未读取的stream=True响应,httpx 会抛出ResponseNotRead,导致 SDK 没有抛出设计文档中承诺的GlobalRouterError。影响 / Impact:
httpx.ResponseNotRead,而不是包含 status、code、message、request_id 的GlobalRouterError。这会破坏调用方的统一错误处理,并让认证、限流、服务端错误更难定位。建议方向 / Suggested fix:
stream()的错误分支中先result.read(),再调用error_from_response(result),最后关闭响应。stream_async()的错误分支中先await result.aread(),再调用error_from_response(result),最后await result.aclose()。验证方式 / Verification:
httpx.Response(429, stream=httpx.ByteStream(...))或等价 mock transport,调用client.chat.stream(...)/client.chat.stream_async(...),断言抛出GlobalRouterError且保留 429、message、router code 等字段,而不是ResponseNotRead。价值 / Value:
价值 / Value
修复该问题可以提升正确性、可靠性和用户信任,降低
unread error response in globalrouter.stream带来的排障与运维成本。Fixing this issue improves correctness, reliability, and user trust while reducing debugging and operational cost caused by
unread error response in globalrouter.stream.证据 / Evidence
File:
src/globalrouter/_client.pyLine: 212
Severity / 严重级别: high
Summary / 摘要: unread error response in globalrouter.stream