# -*- coding: utf-8 -*- """复现 run_agent.py 里两处 `RelayLink.start()` 缺参数的崩溃。 绕过 CLI 参数解析,直接调那两个函数,并把数据目录和 wait_key 换掉, 这样不会碰真实的用户配置、也不会卡在"按任意键继续"。 1. cli_relay_status() —— 不在 try 里,应该会抛未捕获的 TypeError 2. cli_relay() —— 在 try 里,会被吞成"测试失败:..." 功能上等于坏掉(永远报失败) """ from __future__ import annotations import io import sys import tempfile import traceback from contextlib import redirect_stdout from pathlib import Path ROOT = Path(__file__).resolve().parent.parent sys.path.insert(0, str(ROOT / "windows")) tmp = Path(tempfile.mkdtemp(prefix="relaycli_")) def main() -> int: import run_agent from lanremote.config import Store # 把数据目录指到临时目录,wait_key 换成立即返回 run_agent.data_dir = lambda: tmp # type: ignore run_agent.wait_key = lambda *a, **k: None # type: ignore # 造一个"配了中转地址"的设置 store = Store(tmp) store.set("relay_url", "https://relay.example.invalid") print("═══ 1. cli_relay_status()(不在 try 里)═══") buf = io.StringIO() crashed = None try: with redirect_stdout(buf): run_agent.cli_relay_status() except BaseException as exc: # noqa: BLE001 crashed = exc out = buf.getvalue() print(" 它打印的内容:") for line in out.strip().splitlines(): print(" " + line) if crashed is None: print(" (没有抛异常)") else: print(f" 🔴 未捕获异常: {type(crashed).__name__}: {crashed}") tb = traceback.format_exception(type(crashed), crashed, crashed.__traceback__) last = [l for l in "".join(tb).splitlines() if "run_agent.py" in l] for line in last: print(" " + line.strip()) print() print("═══ 2. cli_relay(url)(在 try 里)═══") buf2 = io.StringIO() crashed2 = None try: with redirect_stdout(buf2): rc = run_agent.cli_relay("https://relay.example.invalid") except BaseException as exc: # noqa: BLE001 crashed2 = exc out2 = buf2.getvalue() print(" 它打印的内容:") for line in out2.strip().splitlines(): print(" " + line) if crashed2 is not None: print(f" 🔴 也抛了: {type(crashed2).__name__}: {crashed2}") print(f" 返回值: {rc if crashed2 is None else '(异常)'}") print() print("═══ 3. 结论 ═══") if crashed is not None: print(" 🔴 cli_relay_status 会崩(未捕获)—— " "`ykxmz.exe --relay-status` 直接报栈") if "missing 1 required positional argument" in out2: print(" 🔴 cli_relay 每次都报「测试失败:...missing 1 required " "positional argument: 'url'」——") print(" 地址虽然存下去了(第 281 行先存后测)," "但用户看到的永远是失败提示,") print(" 会以为自己填的地址不对。") return 0 if __name__ == "__main__": sys.exit(main())