diff --git a/.eslintrc.js b/.eslintrc.js index 524a9e183..9e453a9dd 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -15,7 +15,7 @@ module.exports = { 'no-underscore-dangle': [0], 'no-plusplus': [0], 'no-param-reassign': [0], - 'max-len': ['warn', 100, 2, { + 'max-len': ['warn', 120, 2, { ignoreUrls: true, ignoreComments: false, ignoreRegExpLiterals: true, diff --git a/lib/browser/managed_upload.js b/lib/browser/managed_upload.js index 311b58bd8..5c0f6fbb6 100644 --- a/lib/browser/managed_upload.js +++ b/lib/browser/managed_upload.js @@ -17,16 +17,16 @@ const proto = exports; * @param {String} name * @param {String|File} file * @param {Object} options - * {Object} options.callback The callback parameter is composed of a JSON string encoded in Base64 - * {String} options.callback.url the OSS sends a callback request to this URL - * {String} options.callback.host The host header value for initiating callback requests - * {String} options.callback.body The value of the request body when a callback is initiated - * {String} options.callback.contentType The Content-Type of the callback requests initiatiated - * {Object} options.callback.customValue Custom parameters are a map of key-values, e.g: - * customValue = { - * key1: 'value1', - * key2: 'value2' - * } + * {Object} options.callback The callback parameter is composed of a JSON string encoded in Base64 + * {String} options.callback.url the OSS sends a callback request to this URL + * {String} options.callback.host The host header value for initiating callback requests + * {String} options.callback.body The value of the request body when a callback is initiated + * {String} options.callback.contentType The Content-Type of the callback requests initiatiated + * {Object} options.callback.customValue Custom parameters are a map of key-values, e.g: + * customValue = { + * key1: 'value1', + * key2: 'value2' + * } */ proto.multipartUpload = function* multipartUpload(name, file, options) { this.resetCancelFlag(); @@ -107,7 +107,7 @@ proto._resumeMultipart = function* _resumeMultipart(checkpoint, options) { const partOffs = this._divideParts(fileSize, partSize); const numParts = partOffs.length; - const uploadPartJob = function* (self, partNo) { + const uploadPartJob = function* uploadPartJob(self, partNo) { if (!self.isCancel()) { try { const pi = partOffs[partNo - 1]; @@ -117,18 +117,23 @@ proto._resumeMultipart = function* _resumeMultipart(checkpoint, options) { }; const result = yield self._uploadPart(name, uploadId, partNo, data); - doneParts.push({ - number: partNo, - etag: result.res.headers.etag, - }); - checkpoint.doneParts = doneParts; - - if (!self.isCancel() && options && options.progress) { - yield options.progress(doneParts.length / numParts, checkpoint, result.res); + if (!self.isCancel()) { + doneParts.push({ + number: partNo, + etag: result.res.headers.etag, + }); + checkpoint.doneParts = doneParts; + + if (options && options.progress) { + yield options.progress(doneParts.length / numParts, checkpoint, result.res); + } } } catch (err) { - err.partNum = partNo; - throw err; + if (!self.isCancel()) { + self.cancel(); + err.partNum = partNo; + throw err; + } } } }; @@ -156,24 +161,25 @@ proto._resumeMultipart = function* _resumeMultipart(checkpoint, options) { // start uploads jobs const errors = yield this._thunkPool(jobs, parallel); - if (this.isCancel()) { - jobs = null; - throw this._makeCancelEvent(); - } - // check errors after all jobs are completed if (errors && errors.length > 0) { + this.resetCancelFlag(); const err = errors[0]; err.message = `Failed to upload some parts with error: ${err.toString()} part_num: ${err.partNum}`; throw err; } + + if (this.isCancel()) { + jobs = null; + throw this._makeCancelEvent(); + } } return yield this.completeMultipartUpload(name, uploadId, doneParts, options); }; -is.file = function (file) { - return typeof (File) !== 'undefined' && file instanceof File; +is.file = function file(obj) { + return typeof (File) !== 'undefined' && obj instanceof File; }; /** @@ -241,7 +247,7 @@ WebFileReadStream.prototype._read = function _read(size) { size = size || defaultReadSize; const that = this; - this.reader.onload = function (e) { + this.reader.onload = function onload(e) { that.fileBuffer = new Buffer(new Uint8Array(e.target.result)); that.file = null; that.readFileAndPush(size); @@ -270,7 +276,7 @@ proto._createStream = function _createStream(file, start, end) { proto._getPartSize = function _getPartSize(fileSize, partSize) { const maxNumParts = 10 * 1000; - const defaultPartSize = 1 * 1024 * 1024; + const defaultPartSize = 1024 * 1024; if (!partSize) { return defaultPartSize; @@ -300,10 +306,9 @@ proto._divideParts = function _divideParts(fileSize, partSize) { }; // cancel is not error , so create an object -proto._makeCancelEvent = function () { - const cancelEvent = { +proto._makeCancelEvent = function _makeCancelEvent() { + return { status: 0, name: 'cancel', }; - return cancelEvent; }; diff --git a/lib/browser/object.js b/lib/browser/object.js index 25178980d..6ceed25ac 100644 --- a/lib/browser/object.js +++ b/lib/browser/object.js @@ -47,16 +47,16 @@ proto.append = function* (name, file, options) { * @param {String} name the object key * @param {Mixed} file String(file path)/Buffer/ReadableStream * @param {Object} options - * {Object} options.callback The callback parameter is composed of a JSON string encoded in Base64 - * {String} options.callback.url the OSS sends a callback request to this URL - * {String} options.callback.host The host header value for initiating callback requests - * {String} options.callback.body The value of the request body when a callback is initiated - * {String} options.callback.contentType The Content-Type of the callback requests initiatiated - * {Object} options.callback.customValue Custom parameters are a map of key-values, e.g: - * customValue = { - * key1: 'value1', - * key2: 'value2' - * } + * {Object} options.callback The callback parameter is composed of a JSON string encoded in Base64 + * {String} options.callback.url the OSS sends a callback request to this URL + * {String} options.callback.host The host header value for initiating callback requests + * {String} options.callback.body The value of the request body when a callback is initiated + * {String} options.callback.contentType The Content-Type of the callback requests initiatiated + * {Object} options.callback.customValue Custom parameters are a map of key-values, e.g: + * customValue = { + * key1: 'value1', + * key2: 'value2' + * } * @return {Object} */ proto.put = function* put(name, file, options) { diff --git a/lib/common/thunkpool.js b/lib/common/thunkpool.js index 0a6f7e5c1..4c5c2e6c8 100644 --- a/lib/common/thunkpool.js +++ b/lib/common/thunkpool.js @@ -39,7 +39,7 @@ proto._thunkPool = function thunkPool(thunks, parallel) { if (endQueueSum === concurrency) { queue.fns = []; queue.buffer = []; - resolve(); + resolve(_errs); } } diff --git a/lib/managed_upload.js b/lib/managed_upload.js index 8a9cd7e50..031d9e46b 100644 --- a/lib/managed_upload.js +++ b/lib/managed_upload.js @@ -18,16 +18,16 @@ const proto = exports; * @param {String} name * @param {String|File} file * @param {Object} options - * {Object} options.callback The callback parameter is composed of a JSON string encoded in Base64 - * {String} options.callback.url the OSS sends a callback request to this URL - * {String} options.callback.host The host header value for initiating callback requests - * {String} options.callback.body The value of the request body when a callback is initiated - * {String} options.callback.contentType The Content-Type of the callback requests initiatiated - * {Object} options.callback.customValue Custom parameters are a map of key-values, e.g: - * customValue = { - * key1: 'value1', - * key2: 'value2' - * } + * {Object} options.callback The callback parameter is composed of a JSON string encoded in Base64 + * {String} options.callback.url the OSS sends a callback request to this URL + * {String} options.callback.host The host header value for initiating callback requests + * {String} options.callback.body The value of the request body when a callback is initiated + * {String} options.callback.contentType The Content-Type of the callback requests initiatiated + * {Object} options.callback.customValue Custom parameters are a map of key-values, e.g: + * customValue = { + * key1: 'value1', + * key2: 'value2' + * } */ proto.multipartUpload = function* multipartUpload(name, file, options) { options = options || {}; diff --git a/lib/object.js b/lib/object.js index cc9a74b0e..694b2fae6 100644 --- a/lib/object.js +++ b/lib/object.js @@ -44,16 +44,16 @@ proto.append = function* (name, file, options) { * @param {String} name the object key * @param {Mixed} file String(file path)/Buffer/ReadableStream * @param {Object} options - * {Object} options.callback The callback parameter is composed of a JSON string encoded in Base64 - * {String} options.callback.url the OSS sends a callback request to this URL - * {String} options.callback.host The host header value for initiating callback requests - * {String} options.callback.body The value of the request body when a callback is initiated - * {String} options.callback.contentType The Content-Type of the callback requests initiatiated - * {Object} options.callback.customValue Custom parameters are a map of key-values, e.g: - * customValue = { - * key1: 'value1', - * key2: 'value2' - * } + * {Object} options.callback The callback parameter is composed of a JSON string encoded in Base64 + * {String} options.callback.url the OSS sends a callback request to this URL + * {String} options.callback.host The host header value for initiating callback requests + * {String} options.callback.body The value of the request body when a callback is initiated + * {String} options.callback.contentType The Content-Type of the callback requests initiatiated + * {Object} options.callback.customValue Custom parameters are a map of key-values, e.g: + * customValue = { + * key1: 'value1', + * key2: 'value2' + * } * @return {Object} */ proto.put = function* put(name, file, options) { diff --git a/test/browser/browser.test.js b/test/browser/browser.test.js index f20b94fc3..e169bc184 100644 --- a/test/browser/browser.test.js +++ b/test/browser/browser.test.js @@ -786,10 +786,14 @@ describe('browser', () => { const name = `${prefix}multipart/upload-file-exception`; const stubUploadPart = sinon.stub(this.store, '_uploadPart'); - stubUploadPart.throws('TestUploadPartException'); + const testUploadPartException = new Error(); + testUploadPartException.name = 'TestUploadPartException'; + testUploadPartException.status = 403; + stubUploadPart.throws(testUploadPartException); let errorMsg = ''; let partNumz = 0; + let errStatus = 0; try { yield this.store.multipartUpload(name, file, { progress() { @@ -797,16 +801,19 @@ describe('browser', () => { done(); }; }, + partSize: 100 * 1024, }); } catch (err) { errorMsg = err.message; partNumz = err.partNum; + errStatus = err.status; } assert.equal( errorMsg, 'Failed to upload some parts with error: TestUploadPartException part_num: 1', ); assert.equal(partNumz, 1); + assert.equal(errStatus, 403); this.store._uploadPart.restore(); });