fix: isolate attachment submission state

This commit is contained in:
2026-08-24 01:50:04 +08:00
parent bec93d0918
commit 1ca0249e69
8 changed files with 320 additions and 21 deletions

View File

@@ -429,6 +429,55 @@ describe('coding Conversation store', () => {
.toMatchObject({ id: 'node-1', status: 'error' });
});
it('keeps attachment preparation failures out of runtime recovery and permits a direct retry', async () => {
const recover = vi.fn(async () => undefined);
const submitPrompt = vi.fn(async (input) => acceptance(
input.conversationId,
input.clientRequestId,
));
const store = createCodingConversationStore({
getSnapshot: vi.fn(),
openEvents: vi.fn(),
submitPrompt,
recover,
createId: ids(),
});
store.getState().applySnapshotEvent(snapshotEvent(snapshot('conversation-a')));
store.getState().setDraft('conversation-a', 'Inspect the image');
await expect(store.getState().submitPrompt({
conversationId: 'conversation-a',
mode: 'prompt',
prepareAttachments: async () => {
throw new AppError('VALIDATION', '图片附件无效。', undefined, {
backendCode: 'CODING_ATTACHMENT_INVALID',
});
},
})).rejects.toThrow('图片附件无效。');
expect(store.getState().entriesByConversationId['conversation-a']).toMatchObject({
loadState: 'live',
error: null,
});
expect(store.getState().draftsByConversationId['conversation-a'].text)
.toBe('Inspect the image');
expect(store.getState().requestsByConversationId['conversation-a']['request-1'])
.toMatchObject({ status: 'rejected', errorCode: 'CODING_ATTACHMENT_INVALID' });
expect(submitPrompt).not.toHaveBeenCalled();
expect(recover).not.toHaveBeenCalled();
await store.getState().submitPrompt({
conversationId: 'conversation-a',
mode: 'prompt',
prepareAttachments: async () => [{
attachmentId: 'attachment-valid',
mime: 'image/png',
previewUrl: 'blob:valid',
}],
});
expect(submitPrompt).toHaveBeenCalledOnce();
});
it('keeps an uncertain optimistic request recoverable without replaying it on reconnect', async () => {
const source = new FakeEventSource();
const submitPrompt = vi.fn(async () => {