Files
Genarrative/apps/desktop-shell/src-tauri/src/host_bridge/network.rs
T
kdletters bcee92e421 收口桌面壳网络诊断日志
桌面壳网络状态解析失败只记录固定阶段标签

扩展桌面壳配置门禁禁止网络日志输出解析错误细节

补充宿主壳方案和共享决策中的网络诊断边界
2026-06-21 13:38:32 +08:00

107 lines
3.4 KiB
Rust

use crate::host_bridge::protocol::{failed, ok, HostBridgeRequest, HostBridgeResponse};
use crate::shell::webview::resolve_desktop_network_status;
use serde_json::Value;
fn map_desktop_host_bridge_network_status_result(
status: Result<Value, String>,
request: &HostBridgeRequest,
) -> HostBridgeResponse {
match status {
Ok(status) => ok(request.id.clone(), status),
Err(_error) => {
log_desktop_network_failure("status.resolve");
network_status_unavailable_response(request)
}
}
}
async fn resolve_desktop_host_bridge_network_status_payload_with(
resolver: fn() -> Value,
) -> Result<Value, String> {
tauri::async_runtime::spawn_blocking(resolver)
.await
.map_err(|error| error.to_string())
}
async fn resolve_desktop_host_bridge_network_status_payload() -> Result<Value, String> {
resolve_desktop_host_bridge_network_status_payload_with(resolve_desktop_network_status).await
}
pub(crate) async fn resolve_desktop_host_bridge_network_status(
request: &HostBridgeRequest,
) -> HostBridgeResponse {
map_desktop_host_bridge_network_status_result(
resolve_desktop_host_bridge_network_status_payload().await,
request,
)
}
fn network_status_unavailable_response(request: &HostBridgeRequest) -> HostBridgeResponse {
failed(request.id.clone(), "host_error", "network status unavailable")
}
fn log_desktop_network_failure(label: &str) -> bool {
eprintln!("desktop network failed for {label}");
false
}
#[cfg(test)]
mod tests {
use super::*;
use crate::host_bridge::protocol::request;
use serde_json::json;
#[test]
fn network_status_unavailable_response_is_stable() {
let response = network_status_unavailable_response(&request("network.status"));
assert!(!response.ok);
let error = response.error.expect("network status error");
assert_eq!(error.code, "host_error");
assert_eq!(error.message, "network status unavailable");
}
#[test]
fn network_status_success_response_reports_contract_shape() {
let payload = json!({
"isConnected": true,
"isInternetReachable": true,
"connectionType": "unknown",
"nativeType": "online",
});
let response = map_desktop_host_bridge_network_status_result(
Ok(payload.clone()),
&request("network.status"),
);
assert!(response.ok);
assert_eq!(response.id, "request-1");
assert_eq!(response.result, Some(payload));
assert!(response.error.is_none());
}
#[test]
fn network_status_failure_hides_native_error_detail() {
let response = map_desktop_host_bridge_network_status_result(
Err("private native resolver detail".to_string()),
&request("network.status"),
);
assert!(!response.ok);
let error = response.error.expect("network status error");
assert_eq!(error.code, "host_error");
assert_eq!(error.message, "network status unavailable");
assert!(!error.message.contains("private native resolver detail"));
}
#[test]
fn network_status_failures_are_logged_without_exposing_native_detail() {
assert!(!log_desktop_network_failure("status.resolve"));
}
#[test]
fn network_status_failures_log_stable_label_only() {
assert!(!log_desktop_network_failure("status.resolve"));
}
}