Skip to content
This repository was archived by the owner on Jun 26, 2020. It is now read-only.

Commit 8e0e059

Browse files
committed
Cleanup. Removed superfluous tests. Used the file property for simplicity. Tested that the new catch() is safe.
1 parent 6928aa4 commit 8e0e059

File tree

2 files changed

+32
-34
lines changed

2 files changed

+32
-34
lines changed

src/filerepository.js

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -186,19 +186,14 @@ export default class FileRepository extends Plugin {
186186

187187
// Store also file => loader mapping so loader can be retrieved by file instance returned upon Promise resolution.
188188
if ( fileOrPromise instanceof Promise ) {
189-
loader.file.then( file => {
190-
this._loadersMap.set( file, loader );
191-
} ).catch( () => {
192-
// Catch the file promise rejection. If there are no `catch` clause, the browser
193-
// will throw an error (see https://github.com/ckeditor/ckeditor5-upload/pull/90).
194-
// The error will be handled by `FileLoader` so no action is required here.
195-
} );
196-
} else {
197-
// Catch the file promise rejection. If there are no `catch` clause, the browser
198-
// will throw an error (see https://github.com/ckeditor/ckeditor5-upload/pull/90).
199-
loader.file.catch( () => {
200-
// The error will be handled by `FileLoader` so no action is required here.
201-
} );
189+
loader.file
190+
.then( file => {
191+
this._loadersMap.set( file, loader );
192+
} )
193+
// Every then() must have a catch().
194+
// File loader state (and rejections) are handled in read() and upload().
195+
// Also, see the "does not swallow the file promise rejection" test.
196+
.catch( () => {} );
202197
}
203198

204199
loader.on( 'change:uploaded', () => {
@@ -295,7 +290,7 @@ class FileLoader {
295290
/**
296291
* Additional wrapper over the initial file promise passed to this loader.
297292
*
298-
* @private
293+
* @protected
299294
* @member {module:upload/filerepository~FilePromiseWrapper}
300295
*/
301296
this._filePromiseWrapper = this._createFilePromiseWrapper( filePromise );
@@ -442,7 +437,7 @@ class FileLoader {
442437

443438
this.status = 'reading';
444439

445-
return this._filePromiseWrapper.promise
440+
return this.file
446441
.then( file => this._reader.read( file ) )
447442
.then( data => {
448443
// Edge case: reader was aborted after file was read - double check for proper status.
@@ -495,7 +490,7 @@ class FileLoader {
495490

496491
this.status = 'uploading';
497492

498-
return this._filePromiseWrapper.promise
493+
return this.file
499494
.then( () => this._adapter.upload() )
500495
.then( data => {
501496
this.uploadResponse = data;
@@ -521,6 +516,11 @@ class FileLoader {
521516
this.status = 'aborted';
522517

523518
if ( !this._filePromiseWrapper.isFulfilled ) {
519+
// Edge case: file loader is aborted before read() is called
520+
// so it might happen that no one handled the rejection of this promise.
521+
// See https://github.com/ckeditor/ckeditor5-upload/pull/100
522+
this._filePromiseWrapper.promise.catch( () => {} );
523+
524524
this._filePromiseWrapper.rejecter( 'aborted' );
525525
} else if ( status == 'reading' ) {
526526
this._reader.abort();
@@ -555,7 +555,6 @@ class FileLoader {
555555
const wrapper = {};
556556

557557
wrapper.promise = new Promise( ( resolve, reject ) => {
558-
wrapper.resolver = resolve;
559558
wrapper.rejecter = reject;
560559
wrapper.isFulfilled = false;
561560

@@ -631,9 +630,9 @@ mix( FileLoader, ObservableMixin );
631630
* Object returned by {@link module:upload/filerepository~FileLoader#_createFilePromiseWrapper} method
632631
* to add more control over the initial file promise passed to {@link module:upload/filerepository~FileLoader}.
633632
*
633+
* @protected
634634
* @typedef {Object} module:upload/filerepository~FilePromiseWrapper
635635
* @property {Promise.<File>} promise Wrapper promise which can be chained for further processing.
636-
* @property {Function} resolver Resolves the promise when called.
637636
* @property {Function} rejecter Rejects the promise when called.
638637
* @property {Boolean} isFulfilled Whether original promise is already fulfilled.
639638
*/

tests/filerepository.js

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -199,22 +199,22 @@ describe( 'FileRepository', () => {
199199
expect( fileRepository.uploadedPercent ).to.equal( 20 );
200200
} );
201201

202-
it( 'should catch if file promise rejected (file)', () => {
203-
const catchSpy = sinon.spy( Promise.prototype, 'catch' );
204-
205-
fileRepository.createLoader( createNativeFileMock() );
206-
207-
// One call originates from `loader._createFilePromiseWrapper()` and other from `fileRepository.createLoader()`.
208-
expect( catchSpy.callCount ).to.equal( 2 );
209-
} );
210-
211-
it( 'should catch if file promise rejected (promise)', () => {
212-
const catchSpy = sinon.spy( Promise.prototype, 'catch' );
213-
214-
fileRepository.createLoader( new Promise( () => {} ) );
202+
// This is a test for a super edge case when a file promise was rejected,
203+
// but no one called read() or upload() yet. In this case we want to be sure
204+
// that we did not swallow this file promise rejection somewhere in createLoader().
205+
it( 'does not swallow the file promise rejection', done => {
206+
let fileRejecter;
207+
const fileMock = createNativeFileMock();
208+
const filePromise = new Promise( ( resolve, reject ) => {
209+
fileRejecter = reject;
210+
} );
211+
212+
const loader = fileRepository.createLoader( filePromise );
213+
loader.file.catch( () => {
214+
done();
215+
} );
215216

216-
// One call originates from `loader._createFilePromiseWrapper()` and other from `fileRepository.createLoader()`.
217-
expect( catchSpy.callCount ).to.equal( 2 );
217+
fileRejecter( fileMock );
218218
} );
219219
} );
220220

@@ -340,7 +340,6 @@ describe( 'FileRepository', () => {
340340
it( 'should initialize filePromiseWrapper', () => {
341341
expect( loader._filePromiseWrapper ).to.not.be.null;
342342
expect( loader._filePromiseWrapper.promise ).to.be.instanceOf( Promise );
343-
expect( loader._filePromiseWrapper.resolver ).to.be.instanceOf( Function );
344343
expect( loader._filePromiseWrapper.rejecter ).to.be.instanceOf( Function );
345344
expect( loader._filePromiseWrapper.isFulfilled ).to.be.false;
346345
} );

0 commit comments

Comments
 (0)