# -*- coding: utf-8 -*- """修我自己引入的 bug:_post 抛 HTTPError 时没带响应体。 背景: 中转用 **400 + JSON body** 表示"登记被拒"(比如配对码被占)。 _register() 靠读取 HTTPError 的 body 来判断是不是配对码冲突: except urllib.error.HTTPError as exc: body = exc.read(MAX_BODY) 我把 _post 改成复用连接时,抛的是: HTTPError(url, status, "...", headers, None) ^^^^ fp=None fp 是 None,exc.read() 只能返回 b'', 于是 _register 报 "登记响应看不懂:b''" —— 配对码冲突就识别不出来了。 修法: 把已经读到手的 payload 包成 BytesIO 传给 HTTPError, 这样 exc.read() 能拿到真正的响应体,冲突判断恢复正常。 """ from __future__ import annotations import sys from pathlib import Path RELAY = Path(r"C:\Users\shu\Desktop\deepseekagent\LanRemote\windows" r"\lanremote\relay.py") OLD = ''' # 4xx/5xx 也走这里:HTTPError 不带 body,自己判断更清楚 if status >= 400: self._drop_http() if status == 401: raise urllib.error.HTTPError( self.url + path, status, "unauthorized", response.headers, None) raise urllib.error.HTTPError( self.url + path, status, "http error", response.headers, None)''' NEW = ''' # 4xx/5xx:抛 HTTPError,但**必须把响应体带上**。 # 中转用 400 + JSON body 表示"登记被拒"(配对码被占), # 上层要读这个 body 才能区分"码被占"和"普通网络错误"。 # 早先这里传 fp=None,导致 exc.read() 永远是 b'', # 配对码冲突就识别不出来了。 if status >= 400: import io as _io self._drop_http() reason = "unauthorized" if status == 401 else "http error" raise urllib.error.HTTPError( self.url + path, status, reason, response.headers, _io.BytesIO(payload))''' # 401 那条原来的处理路径依赖 HTTPError.code,保持不变 def main() -> int: text = RELAY.read_text(encoding="utf-8") if "_io.BytesIO(payload)" in text: print(" 已经修过") return 0 if OLD not in text: print(" [失败] 锚点没找到") for index, line in enumerate(text.splitlines(), 1): if "HTTPError(" in line and "self.url" in line: print(f" 实际 {index}: {line.strip()}") return 1 text = text.replace(OLD, NEW, 1) RELAY.write_text(text, encoding="utf-8", newline="\n") import ast try: ast.parse(text) print(" 已修:HTTPError 现在带着响应体") except SyntaxError as exc: print(f" 语法错误: 行 {exc.lineno}: {exc.msg}") return 1 # 复核 print(" 复核:") src = RELAY.read_text(encoding="utf-8") print(f" _io.BytesIO(payload) 出现 {src.count('_io.BytesIO(payload)')} 次") print(f" fp=None 还在吗: {'fp=None' in src or ', None)' in src}") return 0 if __name__ == "__main__": sys.exit(main())