补齐 AGC 素材直传的错误文案与能力作用域验证

- AGC:直传对象存储抛错(能力作用域拒绝、网络不可达、请求被取消)时统一转成中文可操作文案,不再把英文插件错误原样暴露给作者。
- 测试:新增直传抛错的单测,确认失败时不再登记素材。
- 文档:记录用 tauri-plugin-http 同一套 urlpattern 逻辑验证 `https://*.aliyuncs.com/*` 命中 dev/生产 OSS 桶且拒绝无关主机,并说明桌面端真实执行仍需在装有 AGC 的机器上补跑。
This commit is contained in:
2026-09-20 22:49:56 +08:00
parent 0dde6ee501
commit 00b96f244d
3 changed files with 38 additions and 4 deletions
@@ -121,10 +121,22 @@ export async function uploadPlatformMediaAsset(args: {
const uploadHost = resolvePlatformAssetUploadUrl(ticket.upload.host);
const uploadFetch = args.fetchImpl ?? tauriHttpFetch;
const uploadResponse = await uploadFetch(uploadHost, {
method: 'POST',
body: buildDirectUploadFormData(ticket.upload, args.file),
});
let uploadResponse: Response;
try {
uploadResponse = await uploadFetch(uploadHost, {
method: 'POST',
body: buildDirectUploadFormData(ticket.upload, args.file),
});
} catch (error) {
// Tauri http 插件在目标不在能力作用域、网络不可达或请求被取消时直接抛错;
// 统一转成可操作文案,避免把英文插件错误原样暴露给作者。
const detail = error instanceof Error ? error.message.trim() : '';
throw new Error(
`上传素材失败:无法访问素材存储,请检查网络后重试${
detail ? `${detail.slice(0, 120)}` : ''
}`,
);
}
if (!uploadResponse.ok) {
throw new Error(
`上传素材到对象存储失败(HTTP ${uploadResponse.status}),请重试`,
@@ -160,6 +160,27 @@ test('对象存储拒绝上传时给出可重试文案', async () => {
expect(requestClientApiMock).toHaveBeenCalledTimes(1);
});
test('直传网络/作用域错误转成可操作文案', async () => {
const uploadFetch = vi.fn(async () => {
throw new Error('url not allowed on the configured scope');
});
await expect(
uploadPlatformMediaAsset({
file: buildCoverFile(),
assetKind: 'game_distribution_cover',
pathSegments: ['game-distribution', 'cover', '42'],
entityId: 'game-distribution-cover',
fetchImpl: uploadFetch,
}),
).rejects.toThrow(
'上传素材失败:无法访问素材存储,请检查网络后重试(url not allowed on the configured scope',
);
// 直传抛错时不得继续登记素材。
expect(requestClientApiMock).toHaveBeenCalledTimes(1);
});
test('本地回环与阿里云 OSS 之外的主机一律拒绝', () => {
expect(resolvePlatformAssetUploadUrl('http://127.0.0.1:9000/bucket')).toBe(
'http://127.0.0.1:9000/bucket',