From 1e19ebb4d99380b6386ee4e3cb0a7eb70f931d49 Mon Sep 17 00:00:00 2001 From: kdletters Date: Sat, 20 Jun 2026 13:54:19 +0800 Subject: [PATCH] =?UTF-8?q?=E9=94=81=E5=AE=9A=E7=A7=BB=E5=8A=A8=E5=A3=B3?= =?UTF-8?q?=E7=BD=91=E7=BB=9C=E7=8A=B6=E6=80=81=E5=A4=B1=E8=B4=A5=E5=93=8D?= =?UTF-8?q?=E5=BA=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 移动端 network.status 读取失败返回稳定 host_error 响应 移动壳网络测试覆盖 Expo Network 异常不透出原生消息 移动壳配置检查反查网络状态失败边界 --- apps/mobile-shell/scripts/check-config.mjs | 27 +++++++++++++++++-- .../src/host-bridge/network.test.ts | 15 ++++++++--- apps/mobile-shell/src/host-bridge/network.ts | 11 ++++++-- 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/apps/mobile-shell/scripts/check-config.mjs b/apps/mobile-shell/scripts/check-config.mjs index 1210a3472..ab9b759da 100644 --- a/apps/mobile-shell/scripts/check-config.mjs +++ b/apps/mobile-shell/scripts/check-config.mjs @@ -2227,6 +2227,27 @@ for (const snippet of [ } } +for (const snippet of [ + 'try {', + 'return ok(request, await getMobileNetworkStatus())', + 'return failure(request, {', + "code: 'host_error'", + "message: 'network status unavailable'", +]) { + if (!hostBridgeNetworkSource.includes(snippet)) { + throw new Error(`mobile shell network HostBridge must stabilize native failures: ${snippet}`); + } +} +for (const snippet of [ + 'converts native network failures to a stable host_error response', + "new Error('network query failed')", + "message: 'network status unavailable'", +]) { + if (!hostBridgeNetworkTestSource.includes(snippet)) { + throw new Error(`mobile shell network tests must cover stable native failure responses: ${snippet}`); + } +} + if ( !hapticsSource.includes('normalizeHostBridgeHapticsImpactStyle(rawStyle)') || !hapticsSource.includes('type HapticsImpactPayload') || @@ -2670,7 +2691,8 @@ if ( for (const snippet of [ 'getMobileHostBridgeNetworkStatus', 'request: HostBridgeRequest', - 'ok(request, await getMobileNetworkStatus())', + 'return ok(request, await getMobileNetworkStatus())', + 'return failure(request, {', 'getMobileNetworkStatus()', ]) { if (!hostBridgeNetworkSource.includes(snippet)) { @@ -2680,10 +2702,11 @@ for (const snippet of [ for (const snippet of [ 'wraps Expo Network status in the HostBridge response shape', 'normalizes disconnected network state before wrapping response', - 'lets protocol layer convert native network failures to host errors', + 'converts native network failures to a stable host_error response', 'connectionType: \'cellular\'', 'connectionType: \'none\'', 'network query failed', + 'network status unavailable', ]) { if (!hostBridgeNetworkTestSource.includes(snippet)) { throw new Error(`mobile shell network tests missing ${snippet}`); diff --git a/apps/mobile-shell/src/host-bridge/network.test.ts b/apps/mobile-shell/src/host-bridge/network.test.ts index f19a27064..579308554 100644 --- a/apps/mobile-shell/src/host-bridge/network.test.ts +++ b/apps/mobile-shell/src/host-bridge/network.test.ts @@ -71,13 +71,20 @@ describe('mobile HostBridge network helper', () => { }); }); - test('lets protocol layer convert native network failures to host errors', async () => { + test('converts native network failures to a stable host_error response', async () => { vi.mocked(Network.getNetworkStateAsync).mockRejectedValue( new Error('network query failed'), ); - await expect(getMobileHostBridgeNetworkStatus(request())).rejects.toThrow( - 'network query failed', - ); + await expect(getMobileHostBridgeNetworkStatus(request())).resolves.toEqual({ + bridge: HOST_BRIDGE_PROTOCOL, + version: HOST_BRIDGE_VERSION, + id: 'network-request', + ok: false, + error: { + code: 'host_error', + message: 'network status unavailable', + }, + }); }); }); diff --git a/apps/mobile-shell/src/host-bridge/network.ts b/apps/mobile-shell/src/host-bridge/network.ts index ef046a42a..18db4ed80 100644 --- a/apps/mobile-shell/src/host-bridge/network.ts +++ b/apps/mobile-shell/src/host-bridge/network.ts @@ -1,9 +1,16 @@ import { getMobileNetworkStatus } from '../shell/network'; import { type HostBridgeRequest } from '../../../../packages/shared/src/contracts/hostBridge'; -import { ok } from './protocol'; +import { failure, ok } from './protocol'; export async function getMobileHostBridgeNetworkStatus( request: HostBridgeRequest, ) { - return ok(request, await getMobileNetworkStatus()); + try { + return ok(request, await getMobileNetworkStatus()); + } catch { + return failure(request, { + code: 'host_error', + message: 'network status unavailable', + }); + } }