diff --git a/evaporate.js b/evaporate.js index 646981ba..86bd0f54 100644 --- a/evaporate.js +++ b/evaporate.js @@ -1422,6 +1422,7 @@ SignedS3AWSRequest.prototype.send.call(self); }); } + return Promise.resolve(); }; PutPart.prototype.success = function () { clearInterval(this.stalledInterval); @@ -1467,14 +1468,31 @@ return [CANCELED, ABORTED, PAUSED, PAUSING].indexOf(this.fileUpload.status) > -1; }; PutPart.prototype.delaySend = function () { + var that = this; var backOffWait = this.backOffWait(); this.attempts += 1; - setTimeout(this.send.bind(this), backOffWait); + setTimeout(function() { + that.send().catch( + function(e) { + l.w(e); + }); + }, backOffWait); }; PutPart.prototype.errorHandler = function (reason) { clearInterval(this.stalledInterval); - if (reason.match(/status:404/)) { - var errMsg = '404 error on part PUT. The part and the file will abort. ' + reason; + var hasError = false; + var errMsg = "Unexpected error occured"; + if (reason instanceof DOMException) { + this.fileUpload.stopMonitor(); + errMsg = reason.message; + hasError = true; + } + else if (reason.match(/status:404/)) { + errMsg = '404 error on part PUT. The part and the file will abort. ' + reason; + hasError = true; + } + + if (hasError) { l.w(errMsg); this.fileUpload.error(errMsg); this.part.status = ABORTED; @@ -1560,16 +1578,18 @@ slicerFn = (file.slice ? 'slice' : (file.mozSlice ? 'mozSlice' : 'webkitSlice')), blob = file[slicerFn](this.start, this.end); if (this.con.computeContentMd5) { - return new Promise(function (resolve) { + return new Promise(function (resolve, reject) { var reader = new FileReader(); reader.onloadend = function () { + if (this.error) { + that.errorHandler(this.error); + reject(this.error.message); + return; + } var buffer = this.result && typeof this.result.buffer !== 'undefined', result = buffer ? new Uint8Array(this.result.buffer) : this.result; resolve(result); }; - reader.onerror = function() { - that.fileUpload.error("Problem occured while reading file " + file.name); - }; reader.readAsArrayBuffer(blob); }); } diff --git a/test/common-case.spec.js b/test/common-case.spec.js index 280277cd..d1fd300d 100644 --- a/test/common-case.spec.js +++ b/test/common-case.spec.js @@ -6,6 +6,11 @@ import test from 'ava' let server +if (!global.DOMException) { + global.DOMException = function() { + this.error = undefined + } +} function testCommon(t, addConfig, initConfig) { let evapConfig = Object.assign({}, {awsSignatureVersion: '2'}, initConfig) return testBase(t, addConfig, evapConfig) @@ -405,3 +410,36 @@ test('should fail with the correctly ordered requests when PUT part 404s and DEL expect(requestOrder(t)).to.match(/initiate,PUT:partNumber=1,cancel,cancel/) }) }) + +// Failure on FileReader read error is propagated +test.serial('should propagate error when FileReader api fails', (t) => { + var arrayBuffer = global['FileReader'].prototype.readAsArrayBuffer; + + global.FileReader.prototype.readAsArrayBuffer = function(blob) + { + this.error = new DOMException(); + this.onloadend(); + }; + + const config = { + name: randomAwsKey(), + file: new File({ + path: '/tmp/file', + size: 8, + name: randomAwsKey() + }), + computeContentMd5: true, + cryptoMd5Method: function () { return 'MD5Value'; }, + } + + return testCommon(t, config, config) + .then( + function (result) { + global['FileReader'].prototype.readAsArrayBuffer = arrayBuffer + t.fail('Expected upload to fail but it did not.') + }, + function (reason) { + global['FileReader'].prototype.readAsArrayBuffer = arrayBuffer + expect(reason).to.match(/aborted/i) + }) +}) \ No newline at end of file