diff --git a/apps/desktop-shell/scripts/check-config.mjs b/apps/desktop-shell/scripts/check-config.mjs index 902d2aff4..631d9e12e 100644 --- a/apps/desktop-shell/scripts/check-config.mjs +++ b/apps/desktop-shell/scripts/check-config.mjs @@ -2185,10 +2185,10 @@ for (const snippet of [ 'resolve_desktop_host_bridge_network_status_payload_with', 'network_status_unavailable_response', 'log_desktop_network_failure', - 'desktop network failed for {label}: {error}', + 'desktop network failed for {label}', 'spawn_blocking(resolver)', 'resolve_desktop_host_bridge_network_status_payload_with(resolve_desktop_network_status)', - 'log_desktop_network_failure("status.resolve", &error)', + 'log_desktop_network_failure("status.resolve")', '"isConnected": true', '"connectionType": "unknown"', '"network status unavailable"', @@ -2196,12 +2196,19 @@ for (const snippet of [ 'network_status_success_response_reports_contract_shape', 'network_status_failure_hides_native_error_detail', 'network_status_failures_are_logged_without_exposing_native_detail', + 'network_status_failures_log_stable_label_only', 'private native resolver detail', ]) { if (!desktopHostBridgeNetworkSource.includes(snippet)) { throw new Error(`desktop shell network module is missing ${snippet}`); } } +if ( + desktopHostBridgeNetworkSource.includes('desktop network failed for {label}: {error}') || + desktopHostBridgeNetworkSource.includes('log_desktop_network_failure("status.resolve", &error)') +) { + throw new Error('desktop shell network module must hide native network errors'); +} if ( !desktopHostBridgeDispatchSource.includes( diff --git a/apps/desktop-shell/src-tauri/src/host_bridge/network.rs b/apps/desktop-shell/src-tauri/src/host_bridge/network.rs index e200a3c76..24a7b565a 100644 --- a/apps/desktop-shell/src-tauri/src/host_bridge/network.rs +++ b/apps/desktop-shell/src-tauri/src/host_bridge/network.rs @@ -8,8 +8,8 @@ fn map_desktop_host_bridge_network_status_result( ) -> HostBridgeResponse { match status { Ok(status) => ok(request.id.clone(), status), - Err(error) => { - log_desktop_network_failure("status.resolve", &error); + Err(_error) => { + log_desktop_network_failure("status.resolve"); network_status_unavailable_response(request) } } @@ -40,11 +40,8 @@ fn network_status_unavailable_response(request: &HostBridgeRequest) -> HostBridg failed(request.id.clone(), "host_error", "network status unavailable") } -fn log_desktop_network_failure(label: &str, error: &str) -> bool { - if !error.is_empty() { - eprintln!("desktop network failed for {label}: {error}"); - } - +fn log_desktop_network_failure(label: &str) -> bool { + eprintln!("desktop network failed for {label}"); false } @@ -99,9 +96,11 @@ mod tests { #[test] fn network_status_failures_are_logged_without_exposing_native_detail() { - assert!(!log_desktop_network_failure( - "status.resolve", - "private network detail" - )); + assert!(!log_desktop_network_failure("status.resolve")); + } + + #[test] + fn network_status_failures_log_stable_label_only() { + assert!(!log_desktop_network_failure("status.resolve")); } } diff --git a/docs/project-memory/shared-memory/decision-log.md b/docs/project-memory/shared-memory/decision-log.md index dfe5ad4b5..6c78daae8 100644 --- a/docs/project-memory/shared-memory/decision-log.md +++ b/docs/project-memory/shared-memory/decision-log.md @@ -3176,6 +3176,7 @@ - 背景:桌面壳 `network.status` 通过后台任务解析系统网络状态,H5 只需要稳定在线 / 离线语义;但后台任务 join 失败时,如果只返回稳定 `host_error`,开发侧无法区分正常离线、解析任务失败和系统异常。 - 决策:`apps/desktop-shell/src-tauri/src/host_bridge/network.rs` 必须在网络状态解析失败时记录 `desktop network failed for status.resolve` 日志。HostBridge 对 H5 仍只返回稳定 `network status unavailable`,不透传 resolver、线程或系统错误细节。 +- 2026-06-21 调整:桌面网络状态解析失败日志只记录 `desktop network failed for status.resolve` 固定标签,不输出后台任务 join 错误、resolver 异常或其它平台细节;配置检查拒绝 `network.rs` 重新拼接 `: {error}` 或把解析错误传给日志函数。 - 验证方式:`cargo test --manifest-path apps/desktop-shell/src-tauri/Cargo.toml host_bridge::network`、`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 099d16f32..32b6f0f09 100644 --- a/docs/【前端架构】ExpoReactNative与Tauri宿主壳方案-2026-06-17.md +++ b/docs/【前端架构】ExpoReactNative与Tauri宿主壳方案-2026-06-17.md @@ -358,7 +358,7 @@ GameBridge 禁止: 2026-06-20 追加:桌面壳导航系统异常必须可观测。Tauri 外链打开失败、同源 H5 route 导航失败、WebView reload 失败或主窗口缺失时,桌面壳必须记录 `desktop navigation failed for ...` 日志;HostBridge 回包仍只暴露稳定 `external URL cannot be opened`、`native page unavailable` 或 `webview reload unavailable` 语义,不透传系统错误、窗口内部信息或平台细节。 -2026-06-20 追加:桌面壳网络状态查询系统异常必须可观测。Tauri 桌面壳后台解析网络状态任务失败时必须记录 `desktop network failed for status.resolve` 日志;HostBridge 回包仍只暴露稳定 `network status unavailable` 语义,不透传 resolver、线程或系统错误细节。 +2026-06-20 追加:桌面壳网络状态查询系统异常必须可观测。Tauri 桌面壳后台解析网络状态任务失败时必须记录 `desktop network failed for status.resolve` 日志;HostBridge 回包仍只暴露稳定 `network status unavailable` 语义,不透传 resolver、线程或系统错误细节。2026-06-21 调整:该日志只记录固定标签,不把后台任务 join 错误或 resolver 异常写入 stderr。 2026-06-20 追加:桌面壳分享缓存内部异常必须可观测。Tauri 桌面壳读写 `share.setTarget` 缓存失败时必须记录 `desktop share failed for ...` 日志;HostBridge 回包仍只暴露稳定 `share unavailable` 语义,不透传锁状态、内部缓存状态或 Rust 同步原语细节。