{"record":{"id":"628bd2b213fd4b95","repo":"BigPizzaV3/CodexPlusPlus","slug":"error-628bd2","errorCode":null,"errorMessage":"微信连接已停止","messagePattern":"微信连接已停止","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"info","filePath":"crates/codex-plus-core/src/connect/mod.rs","lineNumber":297,"sourceCode":"            server\n                .prepare_thread(None)\n                .await\n                .with_context(|| format!(\"恢复原会话失败（{error}），新建会话也失败\"))?\n        }\n        Err(error) => return Err(error),\n    };\n    state\n        .thread_ids\n        .insert(message.from_user_id.clone(), thread_id.clone());\n\n    let turn = server.run_turn(&thread_id, text);\n    tokio::pin!(turn);\n    let turn_result = loop {\n        tokio::select! {\n            reply = &mut turn => break reply?,\n            _ = tokio::time::sleep(std::time::Duration::from_millis(200)) => {\n                if stop.load(Ordering::SeqCst) {\n                    bail!(\"微信连接已停止\");\n                }\n            }\n        }\n    };\n    let reply = if turn_result.reply.trim().is_empty() {\n        \"Codex 已完成处理，但没有返回文字内容。\"\n    } else {\n        turn_result.reply.trim()\n    };\n    let reply_with_footer = append_reply_footer(reply, &turn_result, &app_config.work_dir);\n    client\n        .send_text_chunks(\n            &message.from_user_id,\n            &reply_with_footer,\n            &message.context_token,\n        )\n        .await\n}","sourceCodeStart":279,"sourceCodeEnd":315,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/f2074595a281bc057525c748175c8eb9805b0673/crates/codex-plus-core/src/connect/mod.rs#L279-L315","documentation":"process_weixin_message races the in-flight Codex turn against a 200ms stop-flag poll with tokio::select. When the shared stop AtomicBool is set, the wait branch wins and the turn is aborted with this message. This is an intentional cancellation path, not a malfunction; the outer loop then drops the app-server.","triggerScenarios":"The user clicks stop or disconnect in the Cod++ manager while a message is being processed; the host app shuts down and sets stop during a long turn.","commonSituations":"Stopping the connector during a slow generation; quitting the app mid-turn.","solutions":["Treat it as expected cancellation, nothing to fix, the outer loop already breaks and closes the server","If turns abort instantly at start, check that no other task is setting the stop flag through a stale shared handle","Avoid dispatching new messages after requesting stop"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if stop.load(std::sync::atomic::Ordering::SeqCst) {\n    return Ok(()); // skip dispatching a turn that will be cancelled\n}","typeGuard":null,"tryCatchPattern":"let turn_result = match run_with_stop(&mut server, &thread_id, text, &stop).await {\n    Err(e) if e.to_string().contains(\"微信连接已停止\") => return Ok(()), // clean cancel\n    other => other?,\n};","preventionTips":["Check the stop flag before dispatching each message","Share one stop handle per connector, not per task","Treat this message as cancellation, never as a failure to report"],"tags":["cancellation","weixin","shutdown","tokio-select"],"backgroundTag":"operation-cancelled","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"}