From dcf5dad4b1bba158580dc896f84da4bd322c53c5 Mon Sep 17 00:00:00 2001 From: kdletters <61648117+kdletters@users.noreply.github.com> Date: Tue, 6 Oct 2026 01:48:04 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BB=A7=E7=BB=AD=E6=94=B6=E6=95=9B=E5=8F=97?= =?UTF-8?q?=E6=8E=A7=E5=91=BD=E4=BB=A4=E8=BF=9B=E7=A8=8B=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 保留 leader 身份读取和进程组终止具体原因 保留主进程 kill、wait 与兜底终止正文 --- .../src-tauri/src/command_exec.rs | 37 +++++++++++++------ ...€�里程碑】AGC错误具体文本展示-2026-10-04.md | 1 + 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/apps/ai-game-creator-shell/src-tauri/src/command_exec.rs b/apps/ai-game-creator-shell/src-tauri/src/command_exec.rs index 14a4e6096..aec26aced 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/command_exec.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/command_exec.rs @@ -155,9 +155,11 @@ impl ProjectCommandTree { let pid = child.id().ok_or("受控命令缺少进程身份")?; let start_identity = crate::process_identity::external_agent_runner_process_start_identity(pid) - .ok() - .flatten() + .map_err(|error| format!("受控命令 leader 启动身份读取失败:{error}"))? .filter(|identity| !identity.is_empty()); + if start_identity.is_none() { + return Err("受控命令 leader 启动身份为空,拒绝接管进程组".into()); + } Ok(Self::Group { pid, start_identity, @@ -186,7 +188,7 @@ impl ProjectCommandTree { } let observed = crate::process_identity::external_agent_runner_process_start_identity(*pid) - .map_err(|_| "受控进程组 leader 身份未确认,拒绝发送终止信号")?; + .map_err(|error| format!("受控进程组 leader 身份未确认:{error}"))?; if !owned_project_command_group_identity_matches( start_identity.as_deref(), observed.as_deref(), @@ -207,15 +209,23 @@ impl ProjectCommandTree { { let Self::Job(job) = self; let requested = job.terminate(); - if requested.is_err() { - let _ = child.start_kill(); - } + let fallback_error = requested + .as_ref() + .err() + .and_then(|_| child.start_kill().err()); let deadline = tokio::time::Instant::now() + Duration::from_secs(5); let waited = tokio::time::timeout_at(deadline, child.wait()).await; - requested?; + if let Err(error) = requested { + return Err(match fallback_error { + Some(fallback_error) => { + format!("{error};主进程兜底终止失败:{fallback_error}") + } + None => error, + }); + } waited - .map_err(|_| "等待受控命令主进程退出超时")? - .map_err(|_| "受控命令主进程退出未确认")?; + .map_err(|_| "等待受控命令主进程退出超时:超过 5 秒".to_string())? + .map_err(|error| format!("受控命令主进程退出未确认:{error}"))?; while !job.is_empty()? { if tokio::time::Instant::now() >= deadline { return Err("受控命令 Windows Job 子树退出未确认".into()); @@ -228,11 +238,14 @@ impl ProjectCommandTree { { let deadline = tokio::time::Instant::now() + Duration::from_secs(5); let requested = self.request_owned_group_termination(); - let _ = child.start_kill(); + let child_kill_error = child.start_kill().err(); let waited = tokio::time::timeout_at(deadline, child.wait()).await; + let child_kill_detail = child_kill_error + .map(|error| format!(";主进程兜底终止失败:{error}")) + .unwrap_or_default(); waited - .map_err(|_| "等待受控命令主进程退出超时")? - .map_err(|_| "受控命令主进程退出未确认")?; + .map_err(|_| "等待受控命令主进程退出超时:超过 5 秒".to_string())? + .map_err(|error| format!("受控命令主进程退出未确认:{error}{child_kill_detail}"))?; #[cfg(target_os = "linux")] { let Self::Group { pid, .. } = self; diff --git a/docs/project-memory/plans/【里程碑】AGC错误具体文本展示-2026-10-04.md b/docs/project-memory/plans/【里程碑】AGC错误具体文本展示-2026-10-04.md index 12ba2f1d2..863a33091 100644 --- a/docs/project-memory/plans/【里程碑】AGC错误具体文本展示-2026-10-04.md +++ b/docs/project-memory/plans/【里程碑】AGC错误具体文本展示-2026-10-04.md @@ -93,3 +93,4 @@ DirectProject 回合失败在确认不是客户端内部不可归类故障时, - 策划工作区事件订阅失败仍有一处直接静默结束,导致文件刷新失联却没有提示;现把订阅 IPC 正文写入工作区错误状态,继续保留手动刷新与已有清单读取错误出口。 - 新一轮原生扫出 app-server 进程与上下文漏损:Codex 执行器核验/OAuth 保存/回合身份的 JoinError、图片 base64 解码、Direct 上下文 canonicalize,以及进程树归属、Job、等待、终止和 Drop 清理错误原先只剩固定码;现保留 JoinError、解码器、OS/Job、等待和终止阶段正文,并为进程树 Drop 清理失败写入诊断日志。 - 继续扫出浏览器收割的 Job/root kill/wait 错误原先压成 `bool`、External Editor 本机凭据 JSON/目录创建/保存错误丢底层正文,以及生成任务中断收口把项目清单读取失败当成“状态未知”;现分别保留浏览器清理阶段正文、凭据解析/存储正文,并让非“项目尚未初始化”的清单读取失败直接返回具体错误。 +- 受控 command 执行路径仍会把 leader 启动身份读取、进程组终止、root kill、Job/wait 失败折叠为“身份未确认/退出未确认”;现拒绝无身份接管并保留身份读取、终止兜底、等待和 OS 错误正文。