Skip to content

流式 HTTP 错误响应未读取就解析 / Streaming HTTP errors are parsed before reading #158

@saxon134

Description

@saxon134

问题 / 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-40error_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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions