统一应用壳与工作区错误正文

收敛项目目录、模板、钱包、导入和更新提示的客户端错误脱敏

复用 visibleClientErrorMessage 并补齐资源页调用链
This commit is contained in:
kdletters
2026-10-05 10:43:36 +08:00
parent 9740c39fe4
commit 698d0b9b1e
10 changed files with 41 additions and 51 deletions
@@ -9,6 +9,7 @@ import {
installAppUpdate,
subscribeToAppUpdate,
} from '../services/appUpdate';
import { visibleClientErrorMessage } from '../services/errorReporting';
type DownloadState = 'idle' | 'downloading' | 'completed' | 'error';
@@ -60,7 +61,7 @@ export function AppUpdateNotice() {
await installAppUpdate(setDownloadProgress);
setDownloadState('completed');
} catch (error) {
setDownloadError(error instanceof Error ? error.message : String(error));
setDownloadError(visibleClientErrorMessage(error, '下载更新失败'));
setDownloadState('error');
}
}
@@ -19,6 +19,7 @@ import {
} from 'react';
import { closeDialogOnEscape } from '../../app/dialogs';
import { visibleClientErrorMessage } from '../../services/errorReporting';
import type { RecentProjectRow } from './model';
import type { HomeProjectCreationController } from './useHomeProjectCreation';
import type { RecentProjectsController } from './useRecentProjects';
@@ -236,7 +237,7 @@ export function ProjectsPage({
await recentProjects.refreshRecentWorkspace(renamingPath);
cancelRename();
} catch (error) {
setRenameError(error instanceof Error ? error.message : '重命名项目失败');
setRenameError(visibleClientErrorMessage(error, '重命名项目失败'));
} finally {
setRenameSaving(false);
}
@@ -14,6 +14,7 @@ import {
getClientProfileWalletLedger,
redeemClientProfileRewardCode,
} from '../../services/accountHost';
import { visibleClientErrorMessage } from '../../services/errorReporting';
import { useWalletStore } from '../../stores/useWalletStore';
export function useAccountWallet(currentUserId: string) {
@@ -144,7 +145,7 @@ export function useAccountWallet(currentUserId: string) {
}
setWalletLedger(null);
setWalletLedgerError(
error instanceof Error ? error.message : '读取泥点账单失败',
visibleClientErrorMessage(error, '读取泥点账单失败'),
);
} finally {
if (
@@ -202,7 +203,7 @@ export function useAccountWallet(currentUserId: string) {
currentUserIdRef.current === snapshotOwnerUserId
) {
setRechargeError(
error instanceof Error ? error.message : '读取泥点购买信息失败',
visibleClientErrorMessage(error, '读取泥点购买信息失败'),
);
}
} finally {
@@ -266,7 +267,7 @@ export function useAccountWallet(currentUserId: string) {
redeemLifecycleRef.current === lifecycle &&
currentUserIdRef.current === owner
) {
setRedeemCodeError(error instanceof Error ? error.message : '兑换失败');
setRedeemCodeError(visibleClientErrorMessage(error, '兑换失败'));
}
} finally {
if (
@@ -317,7 +318,7 @@ export function useAccountWallet(currentUserId: string) {
rechargeLifecycleRef.current === rechargeLifecycle &&
currentUserIdRef.current === snapshotOwnerUserId
) {
setRechargeError(error instanceof Error ? error.message : '充值失败');
setRechargeError(visibleClientErrorMessage(error, '充值失败'));
}
} finally {
if (
@@ -36,7 +36,10 @@ import {
createClientOperation,
transitionClientOperation,
} from '../../services/clientOperation';
import { appendWebviewLog } from '../../services/errorReporting';
import {
appendWebviewLog,
visibleClientErrorMessage,
} from '../../services/errorReporting';
import type {
HomeAttachmentDraft,
HomeCreationType,
@@ -141,7 +144,7 @@ export async function uploadLocalFilesAsAttachments(
fileName: file.name,
mediaType,
status: 'failed',
error: error instanceof Error ? error.message : String(error),
error: visibleClientErrorMessage(error),
size: file.size,
});
}
@@ -584,7 +587,7 @@ export function useHomeProjectCreation({
analytics,
);
} catch (error) {
setStatus(error instanceof Error ? error.message : String(error));
setStatus(visibleClientErrorMessage(error));
} finally {
if (projectActionRef.current === 'creating') {
projectActionRef.current = null;
@@ -757,7 +760,7 @@ export function useHomeProjectCreation({
analytics,
);
} catch (error) {
setStatus(error instanceof Error ? error.message : String(error));
setStatus(visibleClientErrorMessage(error));
} finally {
if (projectActionRef.current === 'opening') {
projectActionRef.current = null;
@@ -786,7 +789,7 @@ export function useHomeProjectCreation({
}
await createProjectFromProjectPage(pendingProject.projectPath, true);
} catch (error) {
setStatus(error instanceof Error ? error.message : String(error));
setStatus(visibleClientErrorMessage(error));
}
}
@@ -1033,7 +1036,7 @@ export function useHomeProjectCreation({
setProjectAction(null);
await openProject(selectedPath, 'open', analytics);
} catch (error) {
setStatus(error instanceof Error ? error.message : String(error));
setStatus(visibleClientErrorMessage(error));
} finally {
if (projectActionRef.current === 'opening') {
projectActionRef.current = null;
@@ -1075,7 +1078,7 @@ export function useHomeProjectCreation({
analytics,
);
} catch (error) {
setStatus(error instanceof Error ? error.message : String(error));
setStatus(visibleClientErrorMessage(error));
} finally {
if (projectActionRef.current === 'creating') {
projectActionRef.current = null;
@@ -1,6 +1,7 @@
import { useCallback, useEffect, useRef, useState } from 'react';
import { resolveTauriInvoke } from '../../app/tauri';
import { visibleClientErrorMessage } from '../../services/errorReporting';
import {
readWorkspacePreferences,
setProjectCreationDirectory,
@@ -52,9 +53,7 @@ export function useProjectCreationDirectory() {
});
} catch (error) {
if (!disposed) {
setProjectCreationDirectoryStatus(
error instanceof Error ? error.message : String(error),
);
setProjectCreationDirectoryStatus(visibleClientErrorMessage(error));
}
}
if (disposed) {
@@ -73,9 +72,7 @@ export function useProjectCreationDirectory() {
}
} catch (error) {
if (!disposed) {
setProjectCreationDirectoryStatus(
error instanceof Error ? error.message : String(error),
);
setProjectCreationDirectoryStatus(visibleClientErrorMessage(error));
}
}
};
@@ -116,9 +113,7 @@ export function useProjectCreationDirectory() {
applyWorkspacePreferencesSnapshot(snapshot.projectCreationDirectory);
setProjectCreationDirectoryStatus('已更新项目创建目录');
} catch (error) {
setProjectCreationDirectoryStatus(
error instanceof Error ? error.message : String(error),
);
setProjectCreationDirectoryStatus(visibleClientErrorMessage(error));
} finally {
pickInFlightRef.current = false;
setProjectCreationDirectoryBusy(false);
@@ -132,9 +127,7 @@ export function useProjectCreationDirectory() {
setProjectCreationDirectoryStatus('已恢复默认位置');
})
.catch((error) => {
setProjectCreationDirectoryStatus(
error instanceof Error ? error.message : String(error),
);
setProjectCreationDirectoryStatus(visibleClientErrorMessage(error));
});
}, []);
@@ -9,6 +9,7 @@ import {
import { resolveTauriInvoke } from '../../app/tauri';
import type { LocalProjectDirectoryStatus, TauriInvoke } from '../../app/types';
import { visibleClientErrorMessage } from '../../services/errorReporting';
import {
isAbsoluteProjectPath,
projectPathHasControlCharacter,
@@ -158,9 +159,7 @@ export function useRecentProjects(setStatus: Dispatch<SetStateAction<string>>) {
});
} catch (error) {
if (!disposed) {
setStatusRef.current(
error instanceof Error ? error.message : String(error),
);
setStatusRef.current(visibleClientErrorMessage(error));
}
}
if (disposed) {
@@ -179,9 +178,7 @@ export function useRecentProjects(setStatus: Dispatch<SetStateAction<string>>) {
}
} catch (error) {
if (!disposed) {
setStatusRef.current(
error instanceof Error ? error.message : String(error),
);
setStatusRef.current(visibleClientErrorMessage(error));
}
}
};
@@ -304,9 +301,7 @@ export function useRecentProjects(setStatus: Dispatch<SetStateAction<string>>) {
}
})
.catch((error) => {
setStatusRef.current(
error instanceof Error ? error.message : String(error),
);
setStatusRef.current(visibleClientErrorMessage(error));
});
}
@@ -355,9 +350,7 @@ export function useRecentProjects(setStatus: Dispatch<SetStateAction<string>>) {
});
})
.catch((error) => {
setStatusRef.current(
error instanceof Error ? error.message : String(error),
);
setStatusRef.current(visibleClientErrorMessage(error));
});
}
@@ -382,7 +375,7 @@ export function useRecentProjects(setStatus: Dispatch<SetStateAction<string>>) {
});
setStatus('已打开项目目录');
} catch (error) {
setStatus(error instanceof Error ? error.message : String(error));
setStatus(visibleClientErrorMessage(error));
}
}
@@ -10,6 +10,7 @@ import {
import { resolveTauriInvoke } from '../../app/tauri';
import type { GameCreatorAppConfigView } from '../../app/types';
import { visibleClientErrorMessage } from '../../services/errorReporting';
import {
cachedLlmModelCatalog,
type ClientLlmModel,
@@ -48,8 +49,10 @@ class ModelSelectionConfigError extends Error {}
* 渲染层错误类型,也不把服务端原文(可能含内部地址)直接铺给用户。
*/
function modelCatalogErrorMessage(error: unknown) {
if (error instanceof LlmModelCatalogConfigError) return error.message;
const message = error instanceof Error ? error.message : String(error ?? '');
if (error instanceof LlmModelCatalogConfigError) {
return visibleClientErrorMessage(error);
}
const message = visibleClientErrorMessage(error, '模型列表加载失败');
if (message.includes('authentication-required')) {
return '模型列表加载失败:登录已失效,请重新登录';
}
@@ -1,4 +1,5 @@
import type { TauriInvoke } from '../../app/types';
import { visibleClientErrorMessage } from '../../services/errorReporting';
/** 策划附件只写工作区;返回界面提示,不生成回合附件或资源清单。 */
export async function importDesignFiles(
@@ -18,9 +19,7 @@ export async function importDesignFiles(
});
imported += 1;
} catch (error) {
failures.push(
`${file.name}:${error instanceof Error ? error.message : String(error)}`,
);
failures.push(`${file.name}:${visibleClientErrorMessage(error)}`);
}
}
const summary = `已导入 ${imported} 个文件到策划工作区`;
@@ -14,6 +14,7 @@ import {
beginProjectOpenAnalytics,
type ProjectOpenAnalytics,
} from '../../services/clientAnalytics';
import { visibleClientErrorMessage } from '../../services/errorReporting';
import {
currentPlatformSessionGeneration,
subscribePlatformSessionGeneration,
@@ -45,7 +46,7 @@ type UseTemplateLibraryOptions = {
};
function errorMessage(error: unknown): string {
return error instanceof Error ? error.message : String(error);
return visibleClientErrorMessage(error);
}
export function useTemplateLibrary({
@@ -281,7 +281,7 @@ import {
} from '../../features/resource-canvas/resourceVersionReplacementTransport';
import { useResourceCanvasGenerationPlaceholders } from '../../features/resource-canvas/useResourceCanvasGenerationPlaceholders';
import { createUiDesignDocFromImages } from '../../features/ui-editor/uiDesignResourceBridge';
import { normalizeDiagnosticText } from '../../services/errorReporting';
import { visibleClientErrorMessage } from '../../services/errorReporting';
import {
currentPlatformSessionGeneration,
requestPlatformSessionRefresh,
@@ -521,12 +521,7 @@ function projectDevelopmentErrorMessage(
error: unknown,
fallback = '未提供具体错误正文',
) {
const raw = error instanceof Error ? error.message : String(error ?? '');
const safe = normalizeDiagnosticText(raw.replace(/\s+/gu, ' ').trim()).slice(
0,
400,
);
return safe || fallback;
return visibleClientErrorMessage(error, fallback);
}
function isPlatformAuthenticationRequired(error: unknown) {