3D 提交编排整段落在错误边界内
- src/components/image-editor/model3d-generation/useModel3dGenerationTask.ts:把取占位框、算结果标题与构造提交计划一并移进 try,注入的回调或老快照缺字段导致的抛错不再漏成未捕获 rejection,而是照常写回失败态与提示 - src/components/image-editor/model3d-generation/useModel3dGenerationTask.test.tsx:补「计划构造阶段抛错」的用例(缺 prompt 的老快照)
This commit is contained in:
@@ -276,6 +276,23 @@ describe('useModel3dGenerationTask', () => {
|
||||
expect(result.current.dialog.composerOpen).toBe(true);
|
||||
});
|
||||
|
||||
it('构造提交计划时抛的错也落到失败态,而不是漏成未捕获的 rejection', async () => {
|
||||
// 老快照缺字段:resolveModel3dResultTitle 会读 dialog.prompt.trim(),在计划构造前就抛。
|
||||
const { result } = renderTask({
|
||||
dialog: createDialog({ prompt: undefined }),
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
await result.current.submitModel3dGeneration(
|
||||
createDialog({ prompt: undefined }),
|
||||
);
|
||||
});
|
||||
|
||||
expect(result.current.dialog.status).toBe('failed');
|
||||
expect(result.current.dialog.composerOpen).toBe(true);
|
||||
expect(submitModel3dTextToModelRequestMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('定价段缺失时不发请求,只把不可提交的原因写回面板', async () => {
|
||||
applyEditorGenerationPricingConfig({
|
||||
models: EDITOR_MODEL_MUD_POINT_CONFIG,
|
||||
|
||||
@@ -74,41 +74,43 @@ export function useModel3dGenerationTask({
|
||||
if (!dialogId || !isModel3dGenerationMode(dialog.mode)) {
|
||||
return;
|
||||
}
|
||||
const placeholder = getGeneratingDialogPlaceholder(dialog);
|
||||
const canvasCompletion =
|
||||
projectId && placeholder
|
||||
? {
|
||||
dialogId,
|
||||
title: resolveModel3dResultTitle(dialog),
|
||||
placeholder,
|
||||
}
|
||||
: null;
|
||||
const planResult = buildModel3dSubmissionPlan({
|
||||
dialog,
|
||||
projectId,
|
||||
canvasCompletion,
|
||||
assetFolderId,
|
||||
assetLabel: resolveModel3dResultTitle(dialog),
|
||||
pricing: readEditorModel3dPricingConfig(),
|
||||
});
|
||||
if (!planResult.ok) {
|
||||
// 整个提交编排都落在 try 里:取占位框、算标题、构造提交计划同样可能抛
|
||||
// (注入的回调、老快照缺字段),漏出去就成了一次没有用户提示的未捕获 rejection。
|
||||
try {
|
||||
const placeholder = getGeneratingDialogPlaceholder(dialog);
|
||||
const canvasCompletion =
|
||||
projectId && placeholder
|
||||
? {
|
||||
dialogId,
|
||||
title: resolveModel3dResultTitle(dialog),
|
||||
placeholder,
|
||||
}
|
||||
: null;
|
||||
const planResult = buildModel3dSubmissionPlan({
|
||||
dialog,
|
||||
projectId,
|
||||
canvasCompletion,
|
||||
assetFolderId,
|
||||
assetLabel: resolveModel3dResultTitle(dialog),
|
||||
pricing: readEditorModel3dPricingConfig(),
|
||||
});
|
||||
if (!planResult.ok) {
|
||||
updateCanvasGenerationDialogById(dialogId, (currentDialog) => ({
|
||||
...currentDialog,
|
||||
status: 'failed',
|
||||
composerOpen: true,
|
||||
errorMessage: planResult.message,
|
||||
}));
|
||||
return;
|
||||
}
|
||||
updateCanvasGenerationDialogById(dialogId, (currentDialog) => ({
|
||||
...currentDialog,
|
||||
status: 'failed',
|
||||
composerOpen: true,
|
||||
errorMessage: planResult.message,
|
||||
// 兜底铸的代次要写回状态:否则老快照每次提交都换幂等键,去重保护失效。
|
||||
model3dAttemptNonce: planResult.plan.attemptNonce,
|
||||
status: 'generating',
|
||||
composerOpen: false,
|
||||
errorMessage: undefined,
|
||||
}));
|
||||
return;
|
||||
}
|
||||
updateCanvasGenerationDialogById(dialogId, (currentDialog) => ({
|
||||
...currentDialog,
|
||||
// 兜底铸的代次要写回状态:否则老快照每次提交都换幂等键,去重保护失效。
|
||||
model3dAttemptNonce: planResult.plan.attemptNonce,
|
||||
status: 'generating',
|
||||
composerOpen: false,
|
||||
errorMessage: undefined,
|
||||
}));
|
||||
try {
|
||||
const plan = planResult.plan;
|
||||
// 判别联合在这里收窄:文生与图生各走自己的客户端函数,端点与提交体的配对由类型保证。
|
||||
const response =
|
||||
|
||||
Reference in New Issue
Block a user