@@ -186,17 +186,16 @@ export default class FileRepository extends Plugin {
186
186
187
187
// Store also file => loader mapping so loader can be retrieved by file instance returned upon Promise resolution.
188
188
if ( fileOrPromise instanceof Promise ) {
189
- loader . file . then ( file => {
190
- this . _loadersMap . set ( file , loader ) ;
191
- } ) ;
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 ( ( ) => { } ) ;
192
197
}
193
198
194
- // Catch the file promise rejection. If there are no `catch` clause, the browser
195
- // will throw an error (see https://github.com/ckeditor/ckeditor5-upload/pull/90).
196
- loader . file . catch ( ( ) => {
197
- // The error will be handled by `FileLoader` so no action is required here.
198
- } ) ;
199
-
200
199
loader . on ( 'change:uploaded' , ( ) => {
201
200
let aggregatedUploaded = 0 ;
202
201
@@ -291,7 +290,7 @@ class FileLoader {
291
290
/**
292
291
* Additional wrapper over the initial file promise passed to this loader.
293
292
*
294
- * @private
293
+ * @protected
295
294
* @member {module:upload/filerepository~FilePromiseWrapper}
296
295
*/
297
296
this . _filePromiseWrapper = this . _createFilePromiseWrapper ( filePromise ) ;
@@ -438,9 +437,14 @@ class FileLoader {
438
437
439
438
this . status = 'reading' ;
440
439
441
- return this . _filePromiseWrapper . promise
440
+ return this . file
442
441
. then ( file => this . _reader . read ( file ) )
443
442
. then ( data => {
443
+ // Edge case: reader was aborted after file was read - double check for proper status.
444
+ if ( this . status !== 'reading' ) {
445
+ throw this . status ;
446
+ }
447
+
444
448
this . status = 'idle' ;
445
449
446
450
return data ;
@@ -486,7 +490,7 @@ class FileLoader {
486
490
487
491
this . status = 'uploading' ;
488
492
489
- return this . _filePromiseWrapper . promise
493
+ return this . file
490
494
. then ( ( ) => this . _adapter . upload ( ) )
491
495
. then ( data => {
492
496
this . uploadResponse = data ;
@@ -512,6 +516,11 @@ class FileLoader {
512
516
this . status = 'aborted' ;
513
517
514
518
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
+
515
524
this . _filePromiseWrapper . rejecter ( 'aborted' ) ;
516
525
} else if ( status == 'reading' ) {
517
526
this . _reader . abort ( ) ;
@@ -546,7 +555,6 @@ class FileLoader {
546
555
const wrapper = { } ;
547
556
548
557
wrapper . promise = new Promise ( ( resolve , reject ) => {
549
- wrapper . resolver = resolve ;
550
558
wrapper . rejecter = reject ;
551
559
wrapper . isFulfilled = false ;
552
560
@@ -622,9 +630,9 @@ mix( FileLoader, ObservableMixin );
622
630
* Object returned by {@link module:upload/filerepository~FileLoader#_createFilePromiseWrapper} method
623
631
* to add more control over the initial file promise passed to {@link module:upload/filerepository~FileLoader}.
624
632
*
633
+ * @protected
625
634
* @typedef {Object } module:upload/filerepository~FilePromiseWrapper
626
635
* @property {Promise.<File> } promise Wrapper promise which can be chained for further processing.
627
- * @property {Function } resolver Resolves the promise when called.
628
636
* @property {Function } rejecter Rejects the promise when called.
629
637
* @property {Boolean } isFulfilled Whether original promise is already fulfilled.
630
638
*/
0 commit comments