锁定移动壳原生分享失败响应

移动壳原生分享面板失败返回稳定错误

移动壳分享测试覆盖原生失败不外泄

移动壳配置检查补充分享失败边界反查
This commit is contained in:
2026-06-20 14:17:35 +08:00
parent cf3b02829c
commit 003d3240e3
3 changed files with 32 additions and 5 deletions
@@ -1646,6 +1646,7 @@ for (const snippet of [
"throw invalidRequest('target is required')",
'const normalizedTarget = normalizeHostBridgeShareOpenPayload(target);',
"'share target is invalid'",
"message: 'share unavailable'",
'ok(request, true)',
'resetMobileHostBridgeShareTargetForTest',
]) {
@@ -1669,8 +1670,10 @@ for (const snippet of [
'resetMobileHostBridgeShareTargetForTest()',
'uses cached work target when share.open has no explicit payload',
'keeps the previous cached target when a new target is missing or invalid',
'maps native share sheet failures to stable host errors',
'does not fall back to cached target when explicit payload is unsafe',
'rejects empty share requests before opening native share sheet',
"message: 'share unavailable'",
'https://app.genarrative.world/works/detail?work=PZ-00000001',
'javascript:alert(1)',
'expect(Share.share).not.toHaveBeenCalled()',
@@ -159,6 +159,22 @@ describe('mobile share helpers', () => {
});
});
test('maps native share sheet failures to stable host errors', async () => {
vi.mocked(Share.share).mockRejectedValueOnce(new Error('native share failed'));
await expect(
openShare(
request('share.open', {
title: '测试作品',
url: 'https://app.genarrative.world/works/detail?work=PZ-1',
}),
),
).rejects.toMatchObject({
code: 'host_error',
message: 'share unavailable',
});
});
test.each([
'https://example.com/works/detail?work=PZ-1',
'//example.com/works/detail?work=PZ-1',
+13 -5
View File
@@ -1,6 +1,7 @@
import { Share } from 'react-native';
import {
type HostBridgeError,
type HostBridgeRequest,
normalizeHostBridgeShareOpenPayload,
} from '../../../../packages/shared/src/contracts/hostBridge';
@@ -57,10 +58,17 @@ export async function openShare(request: HostBridgeRequest) {
const url = sharePayload?.url;
const message = [sharePayload?.message, url].filter(Boolean).join('\n');
await Share.share({
title: sharePayload?.title,
message: message || url || sharePayload?.title || '',
url,
});
try {
await Share.share({
title: sharePayload?.title,
message: message || url || sharePayload?.title || '',
url,
});
} catch {
throw {
code: 'host_error',
message: 'share unavailable',
} satisfies HostBridgeError;
}
return ok(request, true);
}