{"record":{"id":"9d2483de39028d87","repo":"BigPizzaV3/CodexPlusPlus","slug":"http-status-9d2483","errorCode":null,"errorMessage":"查询微信扫码状态失败：HTTP {status}","messagePattern":"查询微信扫码状态失败：HTTP (.+?)","errorType":"http","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/codex-plus-core/src/connect/weixin.rs","lineNumber":194,"sourceCode":"            .get(url)\n            .headers(client.route_headers(true)?)\n            .timeout(Duration::from_secs(40))\n            .send()\n            .await;\n        let response = match response {\n            Ok(response) => response,\n            Err(error) if error.is_timeout() => {\n                return Ok(WeixinQrStatus {\n                    status: \"wait\".to_string(),\n                    ..WeixinQrStatus::default()\n                });\n            }\n            Err(error) => return Err(error).context(\"查询微信扫码状态失败\"),\n        };\n        let (status, bytes) =\n            read_response_limited(response, MAX_SMALL_RESPONSE_BYTES, \"微信扫码状态\").await?;\n        if !status.is_success() {\n            bail!(\"查询微信扫码状态失败：HTTP {status}\");\n        }\n        serde_json::from_slice(&bytes).context(\"微信扫码状态响应格式无效\")\n    }\n\n    pub async fn get_updates(\n        &self,\n        get_updates_buf: &str,\n        timeout_ms: u64,\n    ) -> anyhow::Result<WeixinUpdates> {\n        let request_body = json!({\n            \"get_updates_buf\": get_updates_buf,\n            \"base_info\": { \"channel_version\": CHANNEL_VERSION }\n        });\n        let timeout_ms = timeout_ms.clamp(1_000, 60_000);\n        let response = self\n            .client\n            .post(self.endpoint(\"ilink/bot/getupdates\")?)\n            .headers(self.auth_headers()?)","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/f2074595a281bc057525c748175c8eb9805b0673/crates/codex-plus-core/src/connect/weixin.rs#L176-L212","documentation":"poll_qr_status GETs the QR status endpoint with the qr_code string; request timeouts are deliberately tolerated and reported as status wait, so this error means the gateway answered with a real HTTP error status and the polling iteration aborts.","triggerScenarios":"Polling with an expired or invalid qrcode value (4xx); gateway 5xx; base_url or route header mismatches versus the ones used to fetch the code.","commonSituations":"QR code expired server-side while polling continues; IP rate-limited; endpoint changed after a gateway update.","solutions":["Fetch a fresh QR code when the current one is stale or polling keeps failing","Use the same base_url and route headers as the original fetch_qr_code call","Retry with backoff for 5xx and inspect the body for 4xx cause"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"let st = match WeixinClient::poll_qr_status(&base, &tag, &qr.qr_code).await {\n    Ok(st) => st,\n    Err(e) if e.to_string().contains(\"HTTP \") => {\n        let qr = WeixinClient::fetch_qr_code(&base, &tag).await?; // stale code, refresh\n        WeixinClient::poll_qr_status(&base, &tag, &qr.qr_code).await?\n    }\n    Err(e) => return Err(e),\n};","preventionTips":["Refresh the QR code when polls repeatedly fail","Reuse the exact base_url and route headers from the fetch call","Remember timeouts are already tolerated, an error here is a real status"],"tags":["weixin","http","qr-code","polling"],"backgroundTag":"http-error-response","analyzedSha":"f2074595a281bc057525c748175c8eb9805b0673","analyzedAt":"2026-08-23T12:52:24.489Z","contentChangedAt":"2026-08-23T12:52:24.489Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}