{"record":{"id":"db18fda5de281421","repo":"BigPizzaV3/CodexPlusPlus","slug":"http-http-status","errorCode":null,"errorMessage":"微信长轮询请求失败：HTTP {http_status}","messagePattern":"微信长轮询请求失败：HTTP (.+?)","errorType":"http","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/codex-plus-core/src/connect/weixin.rs","lineNumber":234,"sourceCode":"            .await;\n        let response = match response {\n            Ok(response) => response,\n            Err(error) if error.is_timeout() => {\n                return Ok(WeixinUpdates {\n                    ret: 0,\n                    errcode: 0,\n                    errmsg: String::new(),\n                    messages: Vec::new(),\n                    get_updates_buf: get_updates_buf.to_string(),\n                    longpolling_timeout_ms: timeout_ms,\n                });\n            }\n            Err(error) => return Err(error).context(\"微信长轮询请求失败\"),\n        };\n        let (http_status, bytes) =\n            read_response_limited(response, MAX_API_RESPONSE_BYTES, \"微信长轮询\").await?;\n        if !http_status.is_success() {\n            bail!(\"微信长轮询请求失败：HTTP {http_status}\");\n        }\n        let updates: WeixinUpdates =\n            serde_json::from_slice(&bytes).context(\"微信长轮询响应格式无效\")?;\n        if updates.ret != 0 || updates.errcode != 0 {\n            bail!(\n                \"微信长轮询被拒绝：ret={} errcode={} {}\",\n                updates.ret,\n                updates.errcode,\n                updates.errmsg\n            );\n        }\n        Ok(updates)\n    }\n\n    pub async fn send_text_chunks(\n        &self,\n        to_user_id: &str,\n        text: &str,","sourceCodeStart":216,"sourceCodeEnd":252,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/f2074595a281bc057525c748175c8eb9805b0673/crates/codex-plus-core/src/connect/weixin.rs#L216-L252","documentation":"get_updates POSTs the long-poll request; reqwest-level timeouts are tolerated and returned as an empty updates batch, so this error is specifically a non-2xx HTTP status from the getupdates endpoint. The caller run_weixin_connect records it in status and retries after 2 seconds, so single occurrences self-heal.","triggerScenarios":"An invalid or expired token making the gateway answer 401 or 403; gateway 5xx; a malformed get_updates_buf after state corruption; wrong base_url.","commonSituations":"WeChat session expired and needs a re-scan; ilink outage; connector resumed with a stale get_updates_buf.","solutions":["If it persists, re-login by fetching a new QR code and token","Let the built-in 2s retry ride out transient 5xx and watch status.message in the manager","Reset the persisted connect state when get_updates_buf is suspected corrupt","Verify base_url and route_tag"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"// the connector already does this: log, wait, poll again\nmatch client.get_updates(&state.get_updates_buf, timeout_ms).await {\n    Ok(u) => u,\n    Err(e) if e.to_string().contains(\"HTTP \") => {\n        status_message(format!(\"retrying: {e}\"));\n        tokio::time::sleep(Duration::from_secs(2)).await;\n        continue;\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Let the built-in 2s retry handle transient statuses before alerting","Trigger re-login when 401 or 403 repeats","Reset persisted get_updates_buf if corruption is suspected"],"tags":["weixin","http","long-polling","retry"],"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"}