diff --git a/apps/desktop-shell/scripts/check-config.mjs b/apps/desktop-shell/scripts/check-config.mjs index 45632fcd8..eb0556474 100644 --- a/apps/desktop-shell/scripts/check-config.mjs +++ b/apps/desktop-shell/scripts/check-config.mjs @@ -2837,15 +2837,16 @@ for (const snippet of [ 'desktop_appearance_color_scheme', 'appearance_unavailable_response', 'log_desktop_appearance_failure', - 'desktop appearance failed for {label}: {error}', + 'desktop appearance failed for {label}', 'color_scheme_from_theme(theme)', 'window.theme()', - 'log_desktop_appearance_failure("theme", &error.to_string())', - 'log_desktop_appearance_failure("window", "main window unavailable")', + 'log_desktop_appearance_failure("theme")', + 'log_desktop_appearance_failure("window")', '"colorScheme"', '"appearance unavailable"', 'appearance_unavailable_response_is_stable', 'appearance_failures_are_logged_without_exposing_native_detail', + 'appearance_failures_log_stable_label_only', ]) { if (!desktopHostBridgeAppearanceSource.includes(snippet)) { throw new Error(`desktop shell appearance module is missing ${snippet}`); @@ -2853,7 +2854,9 @@ for (const snippet of [ } if ( desktopHostBridgeAppearanceSource.includes('failed(request.id.clone(), "host_error", error.to_string())') || - desktopHostBridgeAppearanceSource.includes('"main window not found"') + desktopHostBridgeAppearanceSource.includes('"main window not found"') || + desktopHostBridgeAppearanceSource.includes('desktop appearance failed for {label}: {error}') || + desktopHostBridgeAppearanceSource.includes('&error.to_string()') ) { throw new Error('desktop shell appearance module must hide native window errors'); } diff --git a/apps/desktop-shell/src-tauri/src/host_bridge/appearance.rs b/apps/desktop-shell/src-tauri/src/host_bridge/appearance.rs index bf49a2a4e..11e4238b2 100644 --- a/apps/desktop-shell/src-tauri/src/host_bridge/appearance.rs +++ b/apps/desktop-shell/src-tauri/src/host_bridge/appearance.rs @@ -10,13 +10,13 @@ pub(crate) fn desktop_appearance_color_scheme( match app.get_webview_window("main") { Some(window) => match window.theme() { Ok(theme) => ok_color_scheme(request, color_scheme_from_theme(theme)), - Err(error) => { - log_desktop_appearance_failure("theme", &error.to_string()); + Err(_error) => { + log_desktop_appearance_failure("theme"); appearance_unavailable_response(request) } }, None => { - log_desktop_appearance_failure("window", "main window unavailable"); + log_desktop_appearance_failure("window"); appearance_unavailable_response(request) } } @@ -35,11 +35,8 @@ fn appearance_unavailable_response(request: &HostBridgeRequest) -> HostBridgeRes failed(request.id.clone(), "host_error", "appearance unavailable") } -fn log_desktop_appearance_failure(label: &str, error: &str) -> bool { - if !error.is_empty() { - eprintln!("desktop appearance failed for {label}: {error}"); - } - +fn log_desktop_appearance_failure(label: &str) -> bool { + eprintln!("desktop appearance failed for {label}"); false } @@ -73,13 +70,12 @@ mod tests { #[test] fn appearance_failures_are_logged_without_exposing_native_detail() { - assert!(!log_desktop_appearance_failure( - "theme", - "private appearance detail" - )); - assert!(!log_desktop_appearance_failure( - "window", - "main window unavailable" - )); + assert!(!log_desktop_appearance_failure("theme")); + assert!(!log_desktop_appearance_failure("window")); + } + + #[test] + fn appearance_failures_log_stable_label_only() { + assert!(!log_desktop_appearance_failure("theme")); } } diff --git a/docs/project-memory/shared-memory/decision-log.md b/docs/project-memory/shared-memory/decision-log.md index 9beecb92c..761638eaa 100644 --- a/docs/project-memory/shared-memory/decision-log.md +++ b/docs/project-memory/shared-memory/decision-log.md @@ -3162,7 +3162,7 @@ - 背景:Tauri 桌面壳的外观、角标和窗口标题能力都依赖主窗口和平台系统 API;这些能力对 H5 必须保持稳定错误语义,但开发侧也需要知道是主窗口缺失、主题读取失败还是系统 API 调用失败。 - 决策:`apps/desktop-shell/src-tauri/src/host_bridge/appearance.rs`、`apps/desktop-shell/src-tauri/src/host_bridge/badge.rs` 和 `apps/desktop-shell/src-tauri/src/host_bridge/title.rs` 必须在主窗口缺失、主题读取失败、角标设置失败和窗口标题设置失败时分别记录 `desktop appearance failed for ...`、`desktop app badge failed for ...` 或 `desktop window title failed for ...` 日志。HostBridge 对 H5 仍只返回稳定 `appearance unavailable`、`badge unavailable` 或 `window title unavailable`,不透传系统错误、窗口内部信息或平台细节。 -- 2026-06-21 调整:桌面角标能力失败日志只记录 `desktop app badge failed for ` 固定标签,不输出主窗口缺失文本、Tauri `set_badge_count` 错误或其它平台细节;配置检查拒绝 `badge.rs` 重新拼接 `: {error}` 或 `&error.to_string()`。 +- 2026-06-21 调整:桌面外观和角标能力失败日志只记录 `desktop appearance failed for ` / `desktop app badge failed for ` 固定标签,不输出主窗口缺失文本、Tauri `theme()` / `set_badge_count` 错误或其它平台细节;配置检查拒绝 `appearance.rs` / `badge.rs` 重新拼接 `: {error}` 或 `&error.to_string()`。 - 验证方式:`cargo test --manifest-path apps/desktop-shell/src-tauri/Cargo.toml host_bridge::appearance`、`cargo test --manifest-path apps/desktop-shell/src-tauri/Cargo.toml host_bridge::badge`、`cargo test --manifest-path apps/desktop-shell/src-tauri/Cargo.toml host_bridge::title`、`npm run desktop-shell:typecheck`、`npm run check:native-shells`、`npm run check:encoding`、`git diff --check`。 ## 2026-06-20 桌面壳导航系统异常必须可观测 diff --git a/docs/【前端架构】ExpoReactNative与Tauri宿主壳方案-2026-06-17.md b/docs/【前端架构】ExpoReactNative与Tauri宿主壳方案-2026-06-17.md index 2b264f50f..24244dd3c 100644 --- a/docs/【前端架构】ExpoReactNative与Tauri宿主壳方案-2026-06-17.md +++ b/docs/【前端架构】ExpoReactNative与Tauri宿主壳方案-2026-06-17.md @@ -354,7 +354,7 @@ GameBridge 禁止: 2026-06-20 追加:桌面壳文件导入导出的系统异常必须可观测。Tauri dialog 路径转换失败、后台文件读写任务失败或任务 join 失败时,桌面壳必须分别记录 `desktop file export failed for ...` 或 `desktop file import failed for ...` 日志;HostBridge 回包仍只暴露稳定 `file export unavailable` 或 `file import unavailable` 语义,不透传本地路径、系统错误或线程细节。用户取消系统文件对话框仍返回 `cancelled`,不记录为异常。 -2026-06-20 追加:桌面壳窗口状态小能力的系统异常必须可观测。Tauri 主窗口缺失、主题读取失败、角标设置失败或窗口标题设置失败时,桌面壳必须分别记录 `desktop appearance failed for ...`、`desktop app badge failed for ...` 或 `desktop window title failed for ...` 日志;HostBridge 回包仍只暴露稳定 `appearance unavailable`、`badge unavailable` 或 `window title unavailable` 语义,不透传系统错误、窗口内部信息或平台细节。2026-06-21 调整:桌面角标失败日志只记录 `desktop app badge failed for ` 固定标签,不把 Tauri `set_badge_count` 错误详情或主窗口缺失细节写入 stderr。 +2026-06-20 追加:桌面壳窗口状态小能力的系统异常必须可观测。Tauri 主窗口缺失、主题读取失败、角标设置失败或窗口标题设置失败时,桌面壳必须分别记录 `desktop appearance failed for ...`、`desktop app badge failed for ...` 或 `desktop window title failed for ...` 日志;HostBridge 回包仍只暴露稳定 `appearance unavailable`、`badge unavailable` 或 `window title unavailable` 语义,不透传系统错误、窗口内部信息或平台细节。2026-06-21 调整:桌面外观和角标失败日志只记录 `desktop appearance failed for ` / `desktop app badge failed for ` 固定标签,不把 Tauri `theme()` / `set_badge_count` 错误详情或主窗口缺失细节写入 stderr。 2026-06-20 追加:桌面壳导航系统异常必须可观测。Tauri 外链打开失败、同源 H5 route 导航失败、WebView reload 失败或主窗口缺失时,桌面壳必须记录 `desktop navigation failed for ...` 日志;HostBridge 回包仍只暴露稳定 `external URL cannot be opened`、`native page unavailable` 或 `webview reload unavailable` 语义,不透传系统错误、窗口内部信息或平台细节。