bcee92e421
桌面壳网络状态解析失败只记录固定阶段标签 扩展桌面壳配置门禁禁止网络日志输出解析错误细节 补充宿主壳方案和共享决策中的网络诊断边界
107 lines
3.4 KiB
Rust
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"));
|
|
}
|
|
}
|