Skip to content

Commit 866cc13

Browse files
author
Kirill Semenov
committed
improve handling of FileReader errors, test added
1 parent 17892c9 commit 866cc13

File tree

2 files changed

+65
-7
lines changed

2 files changed

+65
-7
lines changed

evaporate.js

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1422,6 +1422,7 @@
14221422
SignedS3AWSRequest.prototype.send.call(self);
14231423
});
14241424
}
1425+
return Promise.resolve();
14251426
};
14261427
PutPart.prototype.success = function () {
14271428
clearInterval(this.stalledInterval);
@@ -1467,14 +1468,31 @@
14671468
return [CANCELED, ABORTED, PAUSED, PAUSING].indexOf(this.fileUpload.status) > -1;
14681469
};
14691470
PutPart.prototype.delaySend = function () {
1471+
var that = this;
14701472
var backOffWait = this.backOffWait();
14711473
this.attempts += 1;
1472-
setTimeout(this.send.bind(this), backOffWait);
1474+
setTimeout(function() {
1475+
that.send().catch(
1476+
function(e) {
1477+
l.w(e);
1478+
});
1479+
}, backOffWait);
14731480
};
14741481
PutPart.prototype.errorHandler = function (reason) {
14751482
clearInterval(this.stalledInterval);
1476-
if (reason.match(/status:404/)) {
1477-
var errMsg = '404 error on part PUT. The part and the file will abort. ' + reason;
1483+
var hasError = false;
1484+
var errMsg = "Unexpected error occured";
1485+
if (reason instanceof DOMException) {
1486+
this.fileUpload.stopMonitor();
1487+
errMsg = "Error reading file. " + reason;
1488+
hasError = true;
1489+
}
1490+
else if (reason.match(/status:404/)) {
1491+
errMsg = '404 error on part PUT. The part and the file will abort. ' + reason;
1492+
hasError = true;
1493+
}
1494+
1495+
if (hasError) {
14781496
l.w(errMsg);
14791497
this.fileUpload.error(errMsg);
14801498
this.part.status = ABORTED;
@@ -1560,16 +1578,18 @@
15601578
slicerFn = (file.slice ? 'slice' : (file.mozSlice ? 'mozSlice' : 'webkitSlice')),
15611579
blob = file[slicerFn](this.start, this.end);
15621580
if (this.con.computeContentMd5) {
1563-
return new Promise(function (resolve) {
1581+
return new Promise(function (resolve, reject) {
15641582
var reader = new FileReader();
15651583
reader.onloadend = function () {
1584+
if (this.error) {
1585+
that.errorHandler(this.error);
1586+
reject(this.error.message);
1587+
return;
1588+
}
15661589
var buffer = this.result && typeof this.result.buffer !== 'undefined',
15671590
result = buffer ? new Uint8Array(this.result.buffer) : this.result;
15681591
resolve(result);
15691592
};
1570-
reader.onerror = function() {
1571-
that.fileUpload.error("Problem occured while reading file " + file.name);
1572-
};
15731593
reader.readAsArrayBuffer(blob);
15741594
});
15751595
}

test/common-case.spec.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ import test from 'ava'
66

77
let server
88

9+
if (!global.DOMException) {
10+
global.DOMException = function() {
11+
this.error = undefined
12+
}
13+
}
914
function testCommon(t, addConfig, initConfig) {
1015
let evapConfig = Object.assign({}, {awsSignatureVersion: '2'}, initConfig)
1116
return testBase(t, addConfig, evapConfig)
@@ -405,3 +410,36 @@ test('should fail with the correctly ordered requests when PUT part 404s and DEL
405410
expect(requestOrder(t)).to.match(/initiate,PUT:partNumber=1,cancel,cancel/)
406411
})
407412
})
413+
414+
// Failure on FileReader read error is propagated
415+
test.serial('should propagate error when FileReader api fails', (t) => {
416+
var arrayBuffer = global['FileReader'].prototype.readAsArrayBuffer;
417+
418+
global.FileReader.prototype.readAsArrayBuffer = function(blob)
419+
{
420+
this.error = new DOMException();
421+
this.onloadend();
422+
};
423+
424+
const config = {
425+
name: randomAwsKey(),
426+
file: new File({
427+
path: '/tmp/file',
428+
size: 8,
429+
name: randomAwsKey()
430+
}),
431+
computeContentMd5: true,
432+
cryptoMd5Method: function () { return 'MD5Value'; },
433+
}
434+
435+
return testCommon(t, config, config)
436+
.then(
437+
function (result) {
438+
global['FileReader'].prototype.readAsArrayBuffer = arrayBuffer
439+
t.fail('Expected upload to fail but it did not.')
440+
},
441+
function (reason) {
442+
global['FileReader'].prototype.readAsArrayBuffer = arrayBuffer
443+
expect(reason).to.match(/aborted/i)
444+
})
445+
})

0 commit comments

Comments
 (0)