Skip to content

Commit 64f8d68

Browse files
binghaiwangPeterRao
authored andcommitted
feat(browser): multipartUpload err will cancel this task (#399)
* feat(browser): multipartUpload err will cancel this task * feat(browser): if is cancel not throw parterr * feat: eslint format
1 parent 343938f commit 64f8d68

File tree

7 files changed

+78
-66
lines changed

7 files changed

+78
-66
lines changed

.eslintrc.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ module.exports = {
1515
'no-underscore-dangle': [0],
1616
'no-plusplus': [0],
1717
'no-param-reassign': [0],
18-
'max-len': ['warn', 100, 2, {
18+
'max-len': ['warn', 120, 2, {
1919
ignoreUrls: true,
2020
ignoreComments: false,
2121
ignoreRegExpLiterals: true,

lib/browser/managed_upload.js

Lines changed: 38 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,16 @@ const proto = exports;
1717
* @param {String} name
1818
* @param {String|File} file
1919
* @param {Object} options
20-
* {Object} options.callback The callback parameter is composed of a JSON string encoded in Base64
21-
* {String} options.callback.url the OSS sends a callback request to this URL
22-
* {String} options.callback.host The host header value for initiating callback requests
23-
* {String} options.callback.body The value of the request body when a callback is initiated
24-
* {String} options.callback.contentType The Content-Type of the callback requests initiatiated
25-
* {Object} options.callback.customValue Custom parameters are a map of key-values, e.g:
26-
* customValue = {
27-
* key1: 'value1',
28-
* key2: 'value2'
29-
* }
20+
* {Object} options.callback The callback parameter is composed of a JSON string encoded in Base64
21+
* {String} options.callback.url the OSS sends a callback request to this URL
22+
* {String} options.callback.host The host header value for initiating callback requests
23+
* {String} options.callback.body The value of the request body when a callback is initiated
24+
* {String} options.callback.contentType The Content-Type of the callback requests initiatiated
25+
* {Object} options.callback.customValue Custom parameters are a map of key-values, e.g:
26+
* customValue = {
27+
* key1: 'value1',
28+
* key2: 'value2'
29+
* }
3030
*/
3131
proto.multipartUpload = function* multipartUpload(name, file, options) {
3232
this.resetCancelFlag();
@@ -107,7 +107,7 @@ proto._resumeMultipart = function* _resumeMultipart(checkpoint, options) {
107107
const partOffs = this._divideParts(fileSize, partSize);
108108
const numParts = partOffs.length;
109109

110-
const uploadPartJob = function* (self, partNo) {
110+
const uploadPartJob = function* uploadPartJob(self, partNo) {
111111
if (!self.isCancel()) {
112112
try {
113113
const pi = partOffs[partNo - 1];
@@ -117,18 +117,23 @@ proto._resumeMultipart = function* _resumeMultipart(checkpoint, options) {
117117
};
118118

119119
const result = yield self._uploadPart(name, uploadId, partNo, data);
120-
doneParts.push({
121-
number: partNo,
122-
etag: result.res.headers.etag,
123-
});
124-
checkpoint.doneParts = doneParts;
125-
126-
if (!self.isCancel() && options && options.progress) {
127-
yield options.progress(doneParts.length / numParts, checkpoint, result.res);
120+
if (!self.isCancel()) {
121+
doneParts.push({
122+
number: partNo,
123+
etag: result.res.headers.etag,
124+
});
125+
checkpoint.doneParts = doneParts;
126+
127+
if (options && options.progress) {
128+
yield options.progress(doneParts.length / numParts, checkpoint, result.res);
129+
}
128130
}
129131
} catch (err) {
130-
err.partNum = partNo;
131-
throw err;
132+
if (!self.isCancel()) {
133+
self.cancel();
134+
err.partNum = partNo;
135+
throw err;
136+
}
132137
}
133138
}
134139
};
@@ -156,24 +161,25 @@ proto._resumeMultipart = function* _resumeMultipart(checkpoint, options) {
156161
// start uploads jobs
157162
const errors = yield this._thunkPool(jobs, parallel);
158163

159-
if (this.isCancel()) {
160-
jobs = null;
161-
throw this._makeCancelEvent();
162-
}
163-
164164
// check errors after all jobs are completed
165165
if (errors && errors.length > 0) {
166+
this.resetCancelFlag();
166167
const err = errors[0];
167168
err.message = `Failed to upload some parts with error: ${err.toString()} part_num: ${err.partNum}`;
168169
throw err;
169170
}
171+
172+
if (this.isCancel()) {
173+
jobs = null;
174+
throw this._makeCancelEvent();
175+
}
170176
}
171177
return yield this.completeMultipartUpload(name, uploadId, doneParts, options);
172178
};
173179

174180

175-
is.file = function (file) {
176-
return typeof (File) !== 'undefined' && file instanceof File;
181+
is.file = function file(obj) {
182+
return typeof (File) !== 'undefined' && obj instanceof File;
177183
};
178184

179185
/**
@@ -241,7 +247,7 @@ WebFileReadStream.prototype._read = function _read(size) {
241247
size = size || defaultReadSize;
242248

243249
const that = this;
244-
this.reader.onload = function (e) {
250+
this.reader.onload = function onload(e) {
245251
that.fileBuffer = new Buffer(new Uint8Array(e.target.result));
246252
that.file = null;
247253
that.readFileAndPush(size);
@@ -270,7 +276,7 @@ proto._createStream = function _createStream(file, start, end) {
270276

271277
proto._getPartSize = function _getPartSize(fileSize, partSize) {
272278
const maxNumParts = 10 * 1000;
273-
const defaultPartSize = 1 * 1024 * 1024;
279+
const defaultPartSize = 1024 * 1024;
274280

275281
if (!partSize) {
276282
return defaultPartSize;
@@ -300,10 +306,9 @@ proto._divideParts = function _divideParts(fileSize, partSize) {
300306
};
301307

302308
// cancel is not error , so create an object
303-
proto._makeCancelEvent = function () {
304-
const cancelEvent = {
309+
proto._makeCancelEvent = function _makeCancelEvent() {
310+
return {
305311
status: 0,
306312
name: 'cancel',
307313
};
308-
return cancelEvent;
309314
};

lib/browser/object.js

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,16 @@ proto.append = function* (name, file, options) {
4747
* @param {String} name the object key
4848
* @param {Mixed} file String(file path)/Buffer/ReadableStream
4949
* @param {Object} options
50-
* {Object} options.callback The callback parameter is composed of a JSON string encoded in Base64
51-
* {String} options.callback.url the OSS sends a callback request to this URL
52-
* {String} options.callback.host The host header value for initiating callback requests
53-
* {String} options.callback.body The value of the request body when a callback is initiated
54-
* {String} options.callback.contentType The Content-Type of the callback requests initiatiated
55-
* {Object} options.callback.customValue Custom parameters are a map of key-values, e.g:
56-
* customValue = {
57-
* key1: 'value1',
58-
* key2: 'value2'
59-
* }
50+
* {Object} options.callback The callback parameter is composed of a JSON string encoded in Base64
51+
* {String} options.callback.url the OSS sends a callback request to this URL
52+
* {String} options.callback.host The host header value for initiating callback requests
53+
* {String} options.callback.body The value of the request body when a callback is initiated
54+
* {String} options.callback.contentType The Content-Type of the callback requests initiatiated
55+
* {Object} options.callback.customValue Custom parameters are a map of key-values, e.g:
56+
* customValue = {
57+
* key1: 'value1',
58+
* key2: 'value2'
59+
* }
6060
* @return {Object}
6161
*/
6262
proto.put = function* put(name, file, options) {

lib/common/thunkpool.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ proto._thunkPool = function thunkPool(thunks, parallel) {
3939
if (endQueueSum === concurrency) {
4040
queue.fns = [];
4141
queue.buffer = [];
42-
resolve();
42+
resolve(_errs);
4343
}
4444
}
4545

lib/managed_upload.js

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,16 @@ const proto = exports;
1818
* @param {String} name
1919
* @param {String|File} file
2020
* @param {Object} options
21-
* {Object} options.callback The callback parameter is composed of a JSON string encoded in Base64
22-
* {String} options.callback.url the OSS sends a callback request to this URL
23-
* {String} options.callback.host The host header value for initiating callback requests
24-
* {String} options.callback.body The value of the request body when a callback is initiated
25-
* {String} options.callback.contentType The Content-Type of the callback requests initiatiated
26-
* {Object} options.callback.customValue Custom parameters are a map of key-values, e.g:
27-
* customValue = {
28-
* key1: 'value1',
29-
* key2: 'value2'
30-
* }
21+
* {Object} options.callback The callback parameter is composed of a JSON string encoded in Base64
22+
* {String} options.callback.url the OSS sends a callback request to this URL
23+
* {String} options.callback.host The host header value for initiating callback requests
24+
* {String} options.callback.body The value of the request body when a callback is initiated
25+
* {String} options.callback.contentType The Content-Type of the callback requests initiatiated
26+
* {Object} options.callback.customValue Custom parameters are a map of key-values, e.g:
27+
* customValue = {
28+
* key1: 'value1',
29+
* key2: 'value2'
30+
* }
3131
*/
3232
proto.multipartUpload = function* multipartUpload(name, file, options) {
3333
options = options || {};

lib/object.js

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,16 @@ proto.append = function* (name, file, options) {
4444
* @param {String} name the object key
4545
* @param {Mixed} file String(file path)/Buffer/ReadableStream
4646
* @param {Object} options
47-
* {Object} options.callback The callback parameter is composed of a JSON string encoded in Base64
48-
* {String} options.callback.url the OSS sends a callback request to this URL
49-
* {String} options.callback.host The host header value for initiating callback requests
50-
* {String} options.callback.body The value of the request body when a callback is initiated
51-
* {String} options.callback.contentType The Content-Type of the callback requests initiatiated
52-
* {Object} options.callback.customValue Custom parameters are a map of key-values, e.g:
53-
* customValue = {
54-
* key1: 'value1',
55-
* key2: 'value2'
56-
* }
47+
* {Object} options.callback The callback parameter is composed of a JSON string encoded in Base64
48+
* {String} options.callback.url the OSS sends a callback request to this URL
49+
* {String} options.callback.host The host header value for initiating callback requests
50+
* {String} options.callback.body The value of the request body when a callback is initiated
51+
* {String} options.callback.contentType The Content-Type of the callback requests initiatiated
52+
* {Object} options.callback.customValue Custom parameters are a map of key-values, e.g:
53+
* customValue = {
54+
* key1: 'value1',
55+
* key2: 'value2'
56+
* }
5757
* @return {Object}
5858
*/
5959
proto.put = function* put(name, file, options) {

test/browser/browser.test.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -786,27 +786,34 @@ describe('browser', () => {
786786
const name = `${prefix}multipart/upload-file-exception`;
787787

788788
const stubUploadPart = sinon.stub(this.store, '_uploadPart');
789-
stubUploadPart.throws('TestUploadPartException');
789+
const testUploadPartException = new Error();
790+
testUploadPartException.name = 'TestUploadPartException';
791+
testUploadPartException.status = 403;
792+
stubUploadPart.throws(testUploadPartException);
790793

791794
let errorMsg = '';
792795
let partNumz = 0;
796+
let errStatus = 0;
793797
try {
794798
yield this.store.multipartUpload(name, file, {
795799
progress() {
796800
return function (done) {
797801
done();
798802
};
799803
},
804+
partSize: 100 * 1024,
800805
});
801806
} catch (err) {
802807
errorMsg = err.message;
803808
partNumz = err.partNum;
809+
errStatus = err.status;
804810
}
805811
assert.equal(
806812
errorMsg,
807813
'Failed to upload some parts with error: TestUploadPartException part_num: 1',
808814
);
809815
assert.equal(partNumz, 1);
816+
assert.equal(errStatus, 403);
810817
this.store._uploadPart.restore();
811818
});
812819

0 commit comments

Comments
 (0)