{"record":{"id":"f11a7868430c5262","repo":"BigPizzaV3/CodexPlusPlus","slug":"codex-wechat","errorCode":null,"errorMessage":"\n登录超时。","messagePattern":"\n登录超时。","errorType":"exception","errorClass":"SystemExit","httpStatus":null,"severity":"warning","filePath":"tools/codex-wechat/codex_wechat.py","lineNumber":813,"sourceCode":"            base_url = str(status_resp.get(\"baseurl\") or current_base or ILINK_BASE_URL)\n            user_id = str(status_resp.get(\"ilink_user_id\") or \"\")\n            if not token or not account_id:\n                raise SystemExit(\"扫码成功但没有拿到 bot_token/account_id。\")\n\n            config = load_json_file(output) if output.exists() else {}\n            config.update({\"base_url\": base_url, \"token\": token, \"account_id\": account_id})\n            if user_id:\n                config[\"login_user_id\"] = user_id\n            output.parent.mkdir(parents=True, exist_ok=True)\n            output.write_text(json.dumps(config, ensure_ascii=False, indent=2) + \"\\n\", \"utf-8\")\n            print(f\"\\n登录成功，配置已写入：{output}\")\n            print(\"注意：该文件包含微信 iLink token，不要提交到 Git。\")\n            return\n        elif status == \"expired\":\n            raise SystemExit(\"\\n二维码已过期，请重新运行 login。\")\n        time.sleep(1)\n\n    raise SystemExit(\"\\n登录超时。\")\n\n\ndef main(argv: list[str]) -> int:\n    parser = argparse.ArgumentParser(description=\"Codex WeChat Claw PoC\")\n    sub = parser.add_subparsers(dest=\"command\", required=True)\n\n    run_parser = sub.add_parser(\"run\", help=\"启动 iLink -> codex app-server/exec -> iLink 转发\")\n    run_parser.add_argument(\"--config\", required=True, type=Path, help=\"配置文件路径\")\n\n    login_parser = sub.add_parser(\"login\", help=\"扫码获取 iLink token 并写入配置\")\n    login_parser.add_argument(\"--output\", required=True, type=Path, help=\"要写入的本地配置文件\")\n    login_parser.add_argument(\"--bot-type\", default=\"3\", help=\"iLink bot_type，默认 3\")\n    login_parser.add_argument(\"--timeout\", default=480, type=int, help=\"扫码超时时间，秒\")\n\n    args = parser.parse_args(argv)\n    if args.command == \"run\":\n        poll_loop(load_config(args.config))\n        return 0","sourceCodeStart":795,"sourceCodeEnd":831,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6/tools/codex-wechat/codex_wechat.py#L795-L831","documentation":"qr_login only polls for a fixed duration (args.timeout). If the QR code is neither confirmed nor expired within that window, the polling loop ends and the tool raises SystemExit(\"\\n登录超时。\") — the login attempt is abandoned rather than retried indefinitely. It is the catch-all terminal failure of the QR login flow.","triggerScenarios":"The `for` polling loop in qr_login completes its iterations (elapsed time > timeout) without ever seeing status \"confirmed\" or \"expired\"; raised via `raise SystemExit(\"\\n登录超时。\")` after the loop, reached from `main` with `qr_login(args.output, args.bot_type, args.timeout)`.","commonSituations":"User never scanned the QR code within the timeout; a very short --timeout value was passed; polls silently failing (network errors swallowed, status never matching confirmed/expired) so the loop spins until timeout; iLink endpoint down or returning unexpected statuses.","solutions":["Re-run `codex-wechat login` with a larger --timeout (e.g. --timeout 300) and scan promptly.","Check network connectivity / proxy settings to the iLink base URL; silent poll failures can make the loop run out without status transitions.","Add logging of each poll's status_resp to see whether the server is returning unknown statuses that neither match confirmed nor expired.","Verify the iLink endpoint is up (curl the base URL) before retrying login."],"exampleFix":"// before\nqr_login(args.output, args.bot_type, args.timeout)\n// after\nqr_login(args.output, args.bot_type, max(args.timeout, 300))  # allow enough time to scan","handlingStrategy":"retry","validationCode":"# ensure the endpoint is reachable before starting the poll loop\nimport urllib.request\nurllib.request.urlopen(ILINK_BASE_URL, timeout=5)  # raises early if unreachable","typeGuard":null,"tryCatchPattern":"try:\n    qr_login(output, bot_type, timeout)\nexcept SystemExit as e:\n    if \"登录超时\" in str(e):\n        print(\"tip: scan within the timeout; rerun with a larger --timeout\")","preventionTips":["Pass a generous --timeout (>=300s).","Verify network/proxy access to the iLink base URL before running login.","Log every poll response so silent failures are visible.","Avoid leaving the QR code unscanned while doing something else."],"tags":["login","timeout","polling","network"],"backgroundTag":"request-timeout","analyzedSha":"b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6","analyzedAt":"2026-09-19T23:35:21.129Z","contentChangedAt":"2026-09-19T23:35:21.129Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}