记录桌面网络探测失败
桌面网络状态探测保留 DNS 和 TCP 失败原因日志 桌面壳配置检查拒绝网络探测静默吞错 共享决策日志补充桌面网络探测失败边界
This commit is contained in:
@@ -2279,6 +2279,10 @@ const requiredRustHostSnippets = [
|
||||
'resolve_desktop_lifecycle_window_flag("minimized",',
|
||||
'resolve_desktop_lifecycle_window_flag(\n "focused",',
|
||||
'resolve_desktop_network_status',
|
||||
'resolve_desktop_network_reachability',
|
||||
'log_desktop_network_probe_failure',
|
||||
'desktop network reachability probe failed',
|
||||
'desktop_network_reachability_reports_missing_probe_target',
|
||||
'network.statusChanged',
|
||||
'register_desktop_navigation_events',
|
||||
'desktop_navigation_state_script',
|
||||
@@ -2804,6 +2808,8 @@ for (const blockedLifecycleSnippet of [
|
||||
'let _ = close_window.hide()',
|
||||
'catch (_error) {}',
|
||||
'catch (error) {}',
|
||||
'.to_socket_addrs().ok()',
|
||||
'TcpStream::connect_timeout(&address, timeout)\n .map(',
|
||||
]) {
|
||||
if (rustHostSource.includes(blockedLifecycleSnippet)) {
|
||||
throw new Error(
|
||||
|
||||
@@ -28,21 +28,57 @@ pub(crate) fn desktop_network_status_payload(is_online: bool) -> Value {
|
||||
})
|
||||
}
|
||||
|
||||
fn resolve_desktop_network_reachability(
|
||||
target: Option<(String, u16)>,
|
||||
timeout: Duration,
|
||||
) -> Result<bool, String> {
|
||||
let Some((host, port)) = target else {
|
||||
return Err("network probe target unavailable".to_string());
|
||||
};
|
||||
|
||||
let addresses = (host.as_str(), port)
|
||||
.to_socket_addrs()
|
||||
.map_err(|error| format!("resolve {host}:{port} failed: {error}"))?;
|
||||
let mut resolved_address = false;
|
||||
let mut last_connect_error: Option<String> = None;
|
||||
|
||||
for address in addresses {
|
||||
resolved_address = true;
|
||||
match TcpStream::connect_timeout(&address, timeout) {
|
||||
Ok(stream) => {
|
||||
drop(stream);
|
||||
return Ok(true);
|
||||
}
|
||||
Err(error) => {
|
||||
last_connect_error = Some(error.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !resolved_address {
|
||||
return Err(format!("resolve {host}:{port} returned no addresses"));
|
||||
}
|
||||
|
||||
Err(format!(
|
||||
"connect {host}:{port} failed: {}",
|
||||
last_connect_error.unwrap_or_else(|| "unknown connection error".to_string())
|
||||
))
|
||||
}
|
||||
|
||||
fn log_desktop_network_probe_failure(reason: &str) {
|
||||
eprintln!("desktop network reachability probe failed: {reason}");
|
||||
}
|
||||
|
||||
pub(crate) fn resolve_desktop_network_status() -> Value {
|
||||
let timeout = Duration::from_millis(DESKTOP_NETWORK_CHECK_TIMEOUT_MS);
|
||||
let is_reachable = desktop_network_probe_target()
|
||||
.and_then(|(host, port)| (host.as_str(), port).to_socket_addrs().ok())
|
||||
.map(|addresses| {
|
||||
addresses.into_iter().any(|address| {
|
||||
TcpStream::connect_timeout(&address, timeout)
|
||||
.map(|stream| {
|
||||
drop(stream);
|
||||
true
|
||||
})
|
||||
.unwrap_or(false)
|
||||
})
|
||||
})
|
||||
.unwrap_or(false);
|
||||
let is_reachable =
|
||||
match resolve_desktop_network_reachability(desktop_network_probe_target(), timeout) {
|
||||
Ok(is_reachable) => is_reachable,
|
||||
Err(reason) => {
|
||||
log_desktop_network_probe_failure(&reason);
|
||||
false
|
||||
}
|
||||
};
|
||||
|
||||
desktop_network_status_payload(is_reachable)
|
||||
}
|
||||
@@ -138,4 +174,12 @@ mod tests {
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn desktop_network_reachability_reports_missing_probe_target() {
|
||||
assert_eq!(
|
||||
resolve_desktop_network_reachability(None, Duration::from_millis(1)),
|
||||
Err("network probe target unavailable".to_string())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2916,6 +2916,13 @@
|
||||
- 影响范围:`apps/desktop-shell/src-tauri/src/shell/navigation.rs`、`apps/desktop-shell/scripts/check-config.mjs`。
|
||||
- 验证方式:`cargo test --manifest-path apps/desktop-shell/src-tauri/Cargo.toml shell::navigation`、`npm run desktop-shell:typecheck`、`npm run check:native-shells`、`npm run check:encoding`、`git diff --check`。
|
||||
|
||||
## 2026-06-20 桌面壳网络探测失败不可静默
|
||||
|
||||
- 背景:Tauri 桌面壳 `network.status` 会把主站 TCP 可达性作为当前宿主网络状态;如果探测目标解析、DNS 或 TCP 连接失败后只折叠为 offline,H5 可以收到离线状态,但开发侧无法判断是配置、解析还是连接问题。
|
||||
- 决策:`resolve_desktop_network_status()` 必须通过 `resolve_desktop_network_reachability(...)` 得到可达性或失败原因;失败时记录 `desktop network reachability probe failed: ...`,再继续按离线 payload 返回。配置检查拒绝网络探测重新用 `.to_socket_addrs().ok()` 或 `connect_timeout(...).map(...).unwrap_or(false)` 静默吞错。
|
||||
- 影响范围:`apps/desktop-shell/src-tauri/src/shell/network.rs`、`apps/desktop-shell/scripts/check-config.mjs`。
|
||||
- 验证方式:`cargo test --manifest-path apps/desktop-shell/src-tauri/Cargo.toml shell::network`、`npm run desktop-shell:typecheck`、`npm run check:native-shells`、`npm run check:encoding`、`git diff --check`。
|
||||
|
||||
## 2026-06-20 移动壳 EAS 原生包构建 profile
|
||||
|
||||
- 背景:移动壳已能通过 Expo managed config 和 Metro production bundle smoke,但缺少原生安装包构建 profile;如果只保留 `expo export`,无法证明 Android / iOS 壳有进入原生分发链路的配置。
|
||||
|
||||
Reference in New Issue
Block a user