保留首页创建失败的安全正文
展示脱敏后的 IPC、Provider 与宿主失败原因 补充首页创建错误正文回归测试
This commit is contained in:
@@ -11,6 +11,8 @@
|
||||
* 落回本模块的专用兜底,并按「工作区是否已经建好」分成两条,避免用户重做一遍。
|
||||
*/
|
||||
|
||||
import { visibleClientErrorMessage } from '../../services/errorReporting';
|
||||
|
||||
/** 未分类失败的专用兜底文案。 */
|
||||
export const HOME_CREATION_UNCLASSIFIED_FAILURE = '创建未完成,请重试';
|
||||
|
||||
@@ -64,6 +66,19 @@ function isHomeCreationTransportText(text: string): boolean {
|
||||
);
|
||||
}
|
||||
|
||||
function safeHomeCreationDetail(error: unknown, code?: string) {
|
||||
const detail = visibleClientErrorMessage(error, '').trim();
|
||||
if (!detail) return '';
|
||||
if (!code) return detail;
|
||||
const withoutCode = detail
|
||||
.replace(code, '')
|
||||
.replace(/^\s*[::;;,,-]\s*/u, '')
|
||||
.trim();
|
||||
return withoutCode === code || /[::;;,,-]\s*$/u.test(withoutCode)
|
||||
? ''
|
||||
: withoutCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* 由宿主错误算出用户可见文案。
|
||||
*
|
||||
@@ -76,20 +91,25 @@ export function homeCreationFailureMessage(
|
||||
): string {
|
||||
const projectCreated = options.projectCreated === true;
|
||||
const text = homeCreationDiagnosticText(error);
|
||||
const safeDetail = safeHomeCreationDetail(error);
|
||||
if (isHomeCreationTransportText(text)) {
|
||||
return projectCreated
|
||||
const base = projectCreated
|
||||
? HOME_CREATION_AFTER_PROJECT_IPC_FAILURE
|
||||
: HOME_CREATION_IPC_FAILURE;
|
||||
return safeDetail ? `${base}(${safeDetail})` : base;
|
||||
}
|
||||
const code = HOME_CREATION_HOST_CODE.exec(text)?.[0];
|
||||
if (code) {
|
||||
return projectCreated
|
||||
const base = projectCreated
|
||||
? `工作区已创建;未能进入项目开发(${code});请从「已创建的工作区」打开后重试。`
|
||||
: `创建未完成(${code});请重试。`;
|
||||
const detail = safeHomeCreationDetail(error, code);
|
||||
return detail ? `${base}(${detail})` : base;
|
||||
}
|
||||
return projectCreated
|
||||
const base = projectCreated
|
||||
? HOME_CREATION_AFTER_PROJECT_FAILURE
|
||||
: HOME_CREATION_UNCLASSIFIED_FAILURE;
|
||||
return safeDetail ? `${base}(${safeDetail})` : base;
|
||||
}
|
||||
|
||||
/** 包装成带证据的创建失败;控制器负责把 `diagnostic` 写进日志后再抛出。 */
|
||||
|
||||
@@ -28,7 +28,7 @@ it('宿主机器码原样显示,不落回通用文案', () => {
|
||||
|
||||
it('调用通道失联使用专用 IPC 文案,不冒充业务原因', () => {
|
||||
expect(homeCreationFailureMessage(new Error('Failed to fetch'))).toBe(
|
||||
HOME_CREATION_IPC_FAILURE,
|
||||
`${HOME_CREATION_IPC_FAILURE}(Failed to fetch)`,
|
||||
);
|
||||
expect(
|
||||
homeCreationFailureMessage(
|
||||
@@ -37,12 +37,14 @@ it('调用通道失联使用专用 IPC 文案,不冒充业务原因', () => {
|
||||
),
|
||||
{ projectCreated: true },
|
||||
),
|
||||
).toBe(HOME_CREATION_AFTER_PROJECT_IPC_FAILURE);
|
||||
).toBe(
|
||||
`${HOME_CREATION_AFTER_PROJECT_IPC_FAILURE}(IPC custom protocol failed, Tauri will now use the postMessage interface instead TypeError: Failed to fetch)`,
|
||||
);
|
||||
});
|
||||
|
||||
it('拿不到任何机器码时使用专用兜底,并按是否已建好工作区分文案', () => {
|
||||
expect(homeCreationFailureMessage(new Error('自动创建测试结束'))).toBe(
|
||||
HOME_CREATION_UNCLASSIFIED_FAILURE,
|
||||
`${HOME_CREATION_UNCLASSIFIED_FAILURE}(自动创建测试结束)`,
|
||||
);
|
||||
expect(homeCreationFailureMessage(undefined)).toBe(
|
||||
HOME_CREATION_UNCLASSIFIED_FAILURE,
|
||||
@@ -51,7 +53,9 @@ it('拿不到任何机器码时使用专用兜底,并按是否已建好工作
|
||||
homeCreationFailureMessage(new Error('design runtime unavailable'), {
|
||||
projectCreated: true,
|
||||
}),
|
||||
).toBe(HOME_CREATION_AFTER_PROJECT_FAILURE);
|
||||
).toBe(
|
||||
`${HOME_CREATION_AFTER_PROJECT_FAILURE}(design runtime unavailable)`,
|
||||
);
|
||||
});
|
||||
|
||||
it('宿主原始文本只进诊断,不进用户文案', () => {
|
||||
@@ -60,7 +64,9 @@ it('宿主原始文本只进诊断,不进用户文案', () => {
|
||||
{ projectCreated: false },
|
||||
);
|
||||
expect(failure).toBeInstanceOf(HomeCreationFailure);
|
||||
expect(failure.userMessage).toBe(HOME_CREATION_UNCLASSIFIED_FAILURE);
|
||||
expect(failure.userMessage).toBe(
|
||||
`${HOME_CREATION_UNCLASSIFIED_FAILURE}(Provider 返回 500:<url>)`,
|
||||
);
|
||||
expect(failure.diagnostic).toBe(
|
||||
'Provider 返回 500:https://provider.example/private',
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user