diff --git a/apps/ai-game-creator-shell/src-tauri/src/export/draft/xhs_minitool/commands.rs b/apps/ai-game-creator-shell/src-tauri/src/export/draft/xhs_minitool/commands.rs index beb4b8257..9e17d5972 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/export/draft/xhs_minitool/commands.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/export/draft/xhs_minitool/commands.rs @@ -151,8 +151,15 @@ fn report(command: &'static str, project_path: &str, resu } } +/// 一条失败日志最多记多少个字符。 +/// +/// `CommandFailed` 的 `Debug` 里带着最多 4,000 字符的脚本输出尾部,原样落进 AppData 日志会把一次 +/// 失败撑成好几 KB,去重表也跟着留一份长字符串。日志只需要认得出「哪个变体、哪条命令失败」, +/// 完整现场已经结构化回给前端了。 +const MAX_LOGGED_FAILURE_CHARS: usize = 512; + fn log_failure(command: &'static str, project_path: &str, error: &impl std::fmt::Debug) { - let message = format!("{error:?}"); + let message = bounded_for_log(&format!("{error:?}"), MAX_LOGGED_FAILURE_CHARS); if let Ok(mut last) = LAST_FAILURE.lock() { if last.get(command).is_some_and(|seen| *seen == message) { return; @@ -162,6 +169,15 @@ fn log_failure(command: &'static str, project_path: &str, error: &impl std::fmt: app_log!("export.{command}.failed project={project_path}: {message}"); } +/// 按**字符**(不是字节)截断日志文本,避免切坏 UTF-8;发生截断时补一个省略号说明。 +fn bounded_for_log(message: &str, max_chars: usize) -> String { + if message.chars().count() <= max_chars { + return message.to_string(); + } + let head: String = message.chars().take(max_chars).collect(); + format!("{head}…") +} + fn clear_failure(command: &'static str) { if let Ok(mut last) = LAST_FAILURE.lock() { last.remove(command); @@ -176,7 +192,7 @@ fn short(hash: &str) -> &str { #[cfg(test)] mod tests { - use super::short; + use super::{bounded_for_log, short}; #[test] fn short_keeps_first_eight_characters() { @@ -184,4 +200,11 @@ mod tests { assert_eq!(short("0123"), "0123"); assert_eq!(short(""), ""); } + + #[test] + fn bounded_for_log_keeps_short_text_and_truncates_on_char_boundaries() { + assert_eq!(bounded_for_log("构建失败", 8), "构建失败"); + // 按字符截断:4 个中文字符不会被切坏,末尾补省略号。 + assert_eq!(bounded_for_log("一二三四五六", 4), "一二三四…"); + } }