Skip to content

Commit c72ac45

Browse files
feat: add editor document model save error event (#4658)
* feat: add editor document model save error event * test: cover editor document save error event
1 parent 016e906 commit c72ac45

File tree

3 files changed

+70
-2
lines changed

3 files changed

+70
-2
lines changed

packages/editor/__tests__/browser/doc-model/editor-document-model.test.ts

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import uniqueId from 'lodash/uniqueId';
22

3-
import { IEventBus, URI } from '@opensumi/ide-core-browser';
3+
import { IEventBus, SaveTaskResponseState, URI } from '@opensumi/ide-core-browser';
44
import { IHashCalculateService } from '@opensumi/ide-core-common/lib/hash-calculate/hash-calculate';
55
import { EmptyDocCacheImpl } from '@opensumi/ide-editor/lib/browser/doc-cache';
66
import { monacoApi } from '@opensumi/ide-monaco/lib/browser/monaco-api';
77
import { EOL } from '@opensumi/ide-monaco/lib/browser/monaco-api/types';
8+
import { IMessageService } from '@opensumi/ide-overlay';
89
import { isLinux, isMacintosh } from '@opensumi/monaco-editor-core/esm/vs/base/common/platform';
910

1011
import { createBrowserInjector } from '../../../../../tools/dev-tool/src/injector-helper';
@@ -14,8 +15,11 @@ import { EditorDocumentModel, EditorDocumentModelConstructionOptions } from '../
1415
import {
1516
EditorDocumentModelContentChangedEvent,
1617
EditorDocumentModelOptionChangedEvent,
18+
EditorDocumentModelSaveErrorEvent,
19+
IEditorDocumentModelContentRegistry,
20+
IEditorDocumentModelService,
1721
} from '../../../src/browser/doc-model/types';
18-
import { IDocPersistentCacheProvider } from '../../../src/common';
22+
import { IDocPersistentCacheProvider, SaveReason } from '../../../src/common';
1923

2024
describe('EditorDocumentModel', () => {
2125
let injector: MockInjector;
@@ -209,4 +213,54 @@ describe('EditorDocumentModel', () => {
209213
expect(docModelAny._tryAutoSaveAfterDelay).toBeUndefined();
210214
});
211215
});
216+
217+
describe('save', () => {
218+
let uri: URI;
219+
let docModel: EditorDocumentModel;
220+
let saveEditorDocumentModel: jest.Mock;
221+
let eventBus: IEventBus;
222+
let saveErrorListener: jest.Mock;
223+
let saveErrorDisposer: { dispose(): void };
224+
225+
beforeEach(() => {
226+
uri = new URI(`test://save/${Math.random()}`);
227+
eventBus = injector.get(IEventBus);
228+
injector.mockService(IEditorDocumentModelContentRegistry, {
229+
getProvider: jest.fn().mockResolvedValue({
230+
isReadonly: jest.fn().mockResolvedValue(false),
231+
}),
232+
});
233+
injector.mockService(IMessageService, {
234+
error: jest.fn(),
235+
});
236+
saveEditorDocumentModel = jest.fn().mockResolvedValue({
237+
state: SaveTaskResponseState.ERROR,
238+
errorMessage: 'save failed',
239+
});
240+
injector.mockService(IEditorDocumentModelService, {
241+
saveEditorDocumentModel,
242+
});
243+
docModel = injector.get(EditorDocumentModel, [uri, 'original content', { savable: true }]);
244+
saveErrorListener = jest.fn();
245+
saveErrorDisposer = eventBus.on(EditorDocumentModelSaveErrorEvent, saveErrorListener);
246+
});
247+
248+
afterEach(() => {
249+
saveErrorDisposer.dispose();
250+
docModel.dispose();
251+
});
252+
253+
it('should emit save error event when saving fails', async () => {
254+
docModel.getMonacoModel().setValue('updated content');
255+
256+
const result = await docModel.save(false, SaveReason.AfterDelay);
257+
258+
expect(result).toBe(false);
259+
expect(saveEditorDocumentModel).toHaveBeenCalledTimes(1);
260+
expect(saveErrorListener).toHaveBeenCalledTimes(1);
261+
const event = saveErrorListener.mock.calls[0][0];
262+
expect(event.payload.uri.toString()).toBe(uri.toString());
263+
expect(event.payload.errorMessage).toBe('save failed');
264+
});
265+
});
212266
});

packages/editor/src/browser/doc-model/editor-document-model.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ import {
5656
EditorDocumentModelContentChangedEvent,
5757
EditorDocumentModelOptionChangedEvent,
5858
EditorDocumentModelRemovalEvent,
59+
EditorDocumentModelSaveErrorEvent,
5960
EditorDocumentModelSavedEvent,
6061
EditorDocumentModelWillSaveEvent,
6162
IDocModelUpdateOptions,
@@ -498,6 +499,14 @@ export class EditorDocumentModel extends Disposable implements IEditorDocumentMo
498499
this.eventBus.fire(new EditorDocumentModelSavedEvent(this.uri));
499500
this.setPersist(this.savingTasks[0].alternativeVersionId);
500501
} else {
502+
if (res.state === 'error') {
503+
this.eventBus.fire(
504+
new EditorDocumentModelSaveErrorEvent({
505+
uri: this.uri,
506+
errorMessage: res.errorMessage,
507+
}),
508+
);
509+
}
501510
// 回滚 changes
502511
this.dirtyChanges.unshift(...changes);
503512
}

packages/editor/src/browser/doc-model/types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,11 @@ export class EditorDocumentModelRemovalEvent extends BasicEvent<URI> {}
209209

210210
export class EditorDocumentModelSavedEvent extends BasicEvent<URI> {}
211211

212+
export class EditorDocumentModelSaveErrorEvent extends BasicEvent<{
213+
uri: URI;
214+
errorMessage?: string;
215+
}> {}
216+
212217
export class EditorDocumentModelWillSaveEvent extends BasicEvent<{
213218
uri: URI;
214219
reason: SaveReason;

0 commit comments

Comments
 (0)