8
0
Pārlūkot izejas kodu

Merge pull request #189 from ckeditor/t/186

Fix: ImageUploadEditing throws unhandled async errors. Closes #186.
Oskar Wróbel 7 gadi atpakaļ
vecāks
revīzija
1d3007411e

+ 10 - 3
packages/ckeditor5-image/src/imageupload/imageuploadediting.js

@@ -116,6 +116,7 @@ export default class ImageUploadEditing extends Plugin {
 	 * @private
 	 * @param {module:upload/filerepository~FileLoader} loader
 	 * @param {module:engine/model/element~Element} imageElement
+	 * @returns {Promise}
 	 */
 	_load( loader, imageElement ) {
 		const editor = this.editor;
@@ -128,7 +129,7 @@ export default class ImageUploadEditing extends Plugin {
 			writer.setAttribute( 'uploadStatus', 'reading', imageElement );
 		} );
 
-		loader.read()
+		return loader.read()
 			.then( data => {
 				const viewFigure = editor.editing.mapper.toViewElement( imageElement );
 				const viewImg = viewFigure.getChild( 0 );
@@ -178,10 +179,16 @@ export default class ImageUploadEditing extends Plugin {
 
 				clean();
 			} )
-			.catch( msg => {
+			.catch( error => {
+				// If status is not 'error' nor 'aborted' - throw error because it means that something else went wrong,
+				// it might be generic error and it would be real pain to find what is going on.
+				if ( loader.status !== 'error' && loader.status !== 'aborted' ) {
+					throw error;
+				}
+
 				// Might be 'aborted'.
 				if ( loader.status == 'error' ) {
-					notification.showWarning( msg, {
+					notification.showWarning( error, {
 						title: t( 'Upload failed' ),
 						namespace: 'upload'
 					} );

+ 33 - 0
packages/ckeditor5-image/tests/imageupload/imageuploadediting.js

@@ -289,6 +289,39 @@ describe( 'ImageUploadEditing', () => {
 		}, 0 );
 	} );
 
+	it( 'should throw when other error happens during upload', done => {
+		const file = createNativeFileMock();
+		const error = new Error( 'Foo bar baz' );
+		const uploadEditing = editor.plugins.get( ImageUploadEditing );
+		const loadSpy = sinon.spy( uploadEditing, '_load' );
+		const catchSpy = sinon.spy();
+
+		// Throw an error when async attribute change occur.
+		editor.editing.downcastDispatcher.on( 'attribute:uploadStatus:image', ( evt, data ) => {
+			if ( data.attributeNewValue == 'uploading' ) {
+				throw error;
+			}
+		} );
+
+		setModelData( model, '<paragraph>{}foo bar</paragraph>' );
+		editor.execute( 'imageUpload', { file } );
+
+		sinon.assert.calledOnce( loadSpy );
+
+		const promise = loadSpy.returnValues[ 0 ];
+
+		// Check if error can be caught.
+		promise.catch( catchSpy );
+
+		nativeReaderMock.mockSuccess();
+
+		setTimeout( () => {
+			sinon.assert.calledOnce( catchSpy );
+			sinon.assert.calledWithExactly( catchSpy, error );
+			done();
+		}, 0 );
+	} );
+
 	it( 'should do nothing if image does not have uploadId', () => {
 		setModelData( model, '<image src="image.png"></image>' );