Skip to content

fix(vendor-logging): 修复流式错误日志中文乱码并解耦 antigravity scope 检测;#278

Merged
ThreeFish-AI merged 2 commits into
feature/1.x.xfrom
ThreeFish-AI/fix-log-chinese-encoding
Jul 6, 2026
Merged

fix(vendor-logging): 修复流式错误日志中文乱码并解耦 antigravity scope 检测;#278
ThreeFish-AI merged 2 commits into
feature/1.x.xfrom
ThreeFish-AI/fix-log-chinese-encoding

Conversation

@ThreeFish-AI

Copy link
Copy Markdown
Owner

背景(Why)

上游 4xx/5xx 的流式错误日志此前以 logger.warning("...body=%s...", error_body[:500]) 直接格式化 bytes。Python 对 bytesrepr(),非 ASCII 的 UTF-8 字节被转义为 \xe6\x82\xa8 之类序列——中文错误信息(如上游限流/鉴权提示)在日志中乱码、不可读,直接拖慢线上排障。

变更(What)

  1. 统一解码 helpermodel/vendor.py 新增 decode_error_body(raw, limit=500)——decode("utf-8", errors="replace") 容错解码(非法字节降级为 ,日志路径绝不抛异常),先整体解码再按字符截断(避免在多字节 UTF-8 边界切断产生二次乱码,故 limit 语义为字符数),并经 model/__init__vendors/base 导出复用。
  2. 收敛乱码根因base.py / copilot.py / antigravity.py 三处流式错误日志统一改用该 helper。
  3. 加固 antigravity scope 检测:此前流式路径将截断后的文本同时用于日志展示与 _mark_scope_error_if_needed 的子串检测。当 ACCESS_TOKEN_SCOPE_INSUFFICIENT 标记位于第 500 字符之后时会被截断丢弃,token 不再标记 needs_reauth,持续以 scope 不足的凭证重试。改为检测用完整解码文本、日志展示用截断文本,二者关注点解耦,并恢复与非流式路径(send_message 传完整 response.text)的行为一致性。

实现与测试

  • 新增 tests/test_vendor_helpers.py(7 项):中文可读性、字符截断、非法字节降级、空/ASCII、%s-vs-decode 回归对照,以及经 BaseVendor.send_message_stream 的集成断言。
  • 新增 tests/test_antigravity.py::test_stream_scope_detection_scans_full_body_not_log_truncation:构造标记位于第 500 字符之后的 403 错误体,断言检测仍触发(已实测在旧截断实现下该用例失败,证明其守护有效)。
  • 相关 3 个测试套件共 101 项全部通过;ruff lint/format 通过,pre-commit hooks 全绿。

上游供应商返回 4xx/5xx 时,流式错误分支将 response.aread() 得到的 bytes
经 %s 直接格式化,Python 走 repr() 导致非 ASCII 的 UTF-8 字节被转义为
\xe6\x82\xa8 之类的不可读序列(中文乱码)。

- model/vendor.py 新增公开工具函数 decode_error_body(raw, limit=500):
  先整体 UTF-8 解码(errors="replace" 容忍非法字节)再按字符截断,避免
  在多字节边界切断;作为「错误响应体日志解码」的单一事实源;
- base.py / copilot.py / antigravity.py 三处同型流式错误日志统一复用该
  helper;其中 antigravity 消除了原先重复的 decode 调用(scope 检查与日志
  共用一次解码);
- model 包(vendor.__all__ 与 __init__)同步 re-export;
- 新增 tests/test_vendor_helpers.py:单元测试覆盖中文解码/字符截断/非法字节/
  空值/回归对照,集成测试经 BaseVendor 流式路径(MockTransport 返回 400+中文)
  以 caplog 断言日志含可读中文且无字节转义。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
流式错误路径此前把 decode_error_body(error_body)(截断至前 500 字符)
既用于日志展示、又传入 _mark_scope_error_if_needed 做子串检测。检测这类
判定性逻辑不应受日志展示上限约束:当上游 scope 错误体在
ACCESS_TOKEN_SCOPE_INSUFFICIENT 标记出现前已超过 500 字符时,标记会被
截断丢弃,token 不再标记 needs_reauth 而继续以 scope 不足的凭证重试。

- 检测改用完整解码文本 error_body.decode("utf-8", errors="replace"),
  日志展示仍用 decode_error_body 的 500 字符截断版本,二者关注点解耦;
- 与非流式路径(send_message)传入完整 response.text 的行为恢复一致;
- 补充回归测试:构造标记位于第 500 字符之后的 403 错误体,断言检测仍触发
  (旧截断实现下该用例失败)。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
@ThreeFish-AI ThreeFish-AI merged commit 011d4f6 into feature/1.x.x Jul 6, 2026
6 checks passed
ThreeFish-AI added a commit that referenced this pull request Jul 6, 2026
版本号升级至 0.5.2a8,CHANGELOG 定版。本版收敛 PR #278 两项修复:流式 4xx/5xx
错误日志中文乱码(bytes 经 %s 走 repr() 把 UTF-8 字节转义为不可读序列)经新增
decode_error_body 工具统一收敛;antigravity 流式 scope 检测改用完整解码 body,
与日志展示截断解耦并补回归测试。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant