BigPizzaV3/CodexPlusPlus · info · anyhow::Error

微信连接已停止

Error message

微信连接已停止

What it means

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.

Source

Thrown at crates/codex-plus-core/src/connect/mod.rs:297

            server
                .prepare_thread(None)
                .await
                .with_context(|| format!("恢复原会话失败({error}),新建会话也失败"))?
        }
        Err(error) => return Err(error),
    };
    state
        .thread_ids
        .insert(message.from_user_id.clone(), thread_id.clone());

    let turn = server.run_turn(&thread_id, text);
    tokio::pin!(turn);
    let turn_result = loop {
        tokio::select! {
            reply = &mut turn => break reply?,
            _ = tokio::time::sleep(std::time::Duration::from_millis(200)) => {
                if stop.load(Ordering::SeqCst) {
                    bail!("微信连接已停止");
                }
            }
        }
    };
    let reply = if turn_result.reply.trim().is_empty() {
        "Codex 已完成处理,但没有返回文字内容。"
    } else {
        turn_result.reply.trim()
    };
    let reply_with_footer = append_reply_footer(reply, &turn_result, &app_config.work_dir);
    client
        .send_text_chunks(
            &message.from_user_id,
            &reply_with_footer,
            &message.context_token,
        )
        .await
}

View on GitHub (pinned to f2074595a2)

Solutions

  1. Treat it as expected cancellation, nothing to fix, the outer loop already breaks and closes the server
  2. If turns abort instantly at start, check that no other task is setting the stop flag through a stale shared handle
  3. Avoid dispatching new messages after requesting stop
Defensive patterns

Strategy: validation

Validate before calling

if stop.load(std::sync::atomic::Ordering::SeqCst) {
    return Ok(()); // skip dispatching a turn that will be cancelled
}

Try / catch

let turn_result = match run_with_stop(&mut server, &thread_id, text, &stop).await {
    Err(e) if e.to_string().contains("微信连接已停止") => return Ok(()), // clean cancel
    other => other?,
};

Prevention

When it happens

Trigger: 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.

Common situations: Stopping the connector during a slow generation; quitting the app mid-turn.

Related errors


AI-assisted analysis of BigPizzaV3/CodexPlusPlus@f2074595a2 (2026-08-23). Data as JSON: /api/errors/628bd2b213fd4b95. Report an issue: GitHub.