From 439ffded0bf9f8b9e73bed9a917d5265b80e8286 Mon Sep 17 00:00:00 2001 From: YunZZY <1263206327@qq.com> Date: Mon, 18 Nov 2024 10:48:03 +0800 Subject: [PATCH] fix: fix requestError return null and signatureV4 run in Node 8.x (#1338) Co-authored-by: zhengzuoyu.zzy --- lib/browser/client.js | 11 +++++---- lib/client.js | 11 +++++---- lib/common/object/signatureUrlV4.js | 4 ++-- lib/common/signUtils.js | 2 +- test/browser/browser.test.js | 37 +++++++++++++++++++++++++++++ test/node/multipart.test.js | 37 +++++++++++++++++++++++++++++ test/node/rtmp.test.js | 2 +- 7 files changed, 90 insertions(+), 14 deletions(-) diff --git a/lib/browser/client.js b/lib/browser/client.js index f8868f2c..6026a5ff 100644 --- a/lib/browser/client.js +++ b/lib/browser/client.js @@ -400,7 +400,7 @@ proto.requestError = async function requestError(result) { this.debug(message, 'error'); error.message += `\nraw xml: ${message}`; error.status = result.status; - error.requestId = result.headers['x-oss-request-id']; + error.requestId = result.headers && result.headers['x-oss-request-id']; return error; } @@ -416,6 +416,7 @@ proto.requestError = async function requestError(result) { err.requestId = info.RequestId; err.hostId = info.HostId; err.serverTime = info.ServerTime; + return err; }; if (!result.data || !result.data.length) { @@ -442,20 +443,20 @@ proto.requestError = async function requestError(result) { err.name = 'UnknownError'; err.status = result.status; err.res = result; - const ossErr = result.headers['x-oss-err']; + const ossErr = result.headers && result.headers['x-oss-err']; if (ossErr) { const message = atob(ossErr); - await setError(message); + err = await setError(message); } } - err.requestId = result.headers['x-oss-request-id']; + err.requestId = result.headers && result.headers['x-oss-request-id']; err.host = ''; } } else { const message = String(result.data); this.debug('request response error data: %s', message, 'error'); - await setError(message); + err = await setError(message); } this.debug('generate error %j', err, 'error'); diff --git a/lib/client.js b/lib/client.js index d2fa1929..71f36791 100644 --- a/lib/client.js +++ b/lib/client.js @@ -365,7 +365,7 @@ proto.requestError = async function requestError(result) { debug(message); error.message += `\nraw xml: ${message}`; error.status = result.status; - error.requestId = result.headers['x-oss-request-id']; + error.requestId = result.headers && result.headers['x-oss-request-id']; return error; } @@ -380,6 +380,7 @@ proto.requestError = async function requestError(result) { err.requestId = info.RequestId; err.ecCode = info.EC; err.hostId = info.HostId; + return err; }; if (result.name === 'ResponseTimeoutError') { @@ -409,20 +410,20 @@ proto.requestError = async function requestError(result) { err.name = 'UnknownError'; err.status = result.status; err.res = result; - const ossErr = result.headers['x-oss-err']; + const ossErr = result.headers && result.headers['x-oss-err']; if (ossErr) { const message = Buffer.from(ossErr, 'base64').toString('utf8'); - await setError(message); + err = await setError(message); } } - err.requestId = result.headers['x-oss-request-id']; + err.requestId = result.headers && result.headers['x-oss-request-id']; err.host = ''; } } else { const message = String(result.data); debug('request response error data: %s', message); - await setError(message); + err = await setError(message); } debug('generate error %j', err); diff --git a/lib/common/object/signatureUrlV4.js b/lib/common/object/signatureUrlV4.js index dbc9b55d..01dfebcb 100644 --- a/lib/common/object/signatureUrlV4.js +++ b/lib/common/object/signatureUrlV4.js @@ -21,7 +21,7 @@ const proto = exports; */ proto.signatureUrlV4 = async function signatureUrlV4(method, expires, request, objectName, additionalHeaders) { const headers = (request && request.headers) || {}; - const queries = { ...((request && request.queries) || {}) }; + const queries = Object.assign({}, (request && request.queries) || {}); const date = new Date(); const formattedDate = dateFormat(date, "UTC:yyyymmdd'T'HHMMss'Z'"); const onlyDate = formattedDate.split('T')[0]; @@ -64,7 +64,7 @@ proto.signatureUrlV4 = async function signatureUrlV4(method, expires, request, o object: objectName }) ); - signedUrl.query = { ...queries }; + signedUrl.query = Object.assign({}, queries); return signedUrl.format(); }; diff --git a/lib/common/signUtils.js b/lib/common/signUtils.js index 2781b2e6..fcc3a3cd 100644 --- a/lib/common/signUtils.js +++ b/lib/common/signUtils.js @@ -168,7 +168,7 @@ exports.getCanonicalRequest = function getCanonicalRequest(method, request, buck signContent.push(canonicalHeaders); // Additional Headers - if (additionalHeaders.length > 0) { + if (additionalHeaders && additionalHeaders.length > 0) { signContent.push(additionalHeaders.join(';')); } else { signContent.push(''); diff --git a/test/browser/browser.test.js b/test/browser/browser.test.js index ad9a8abb..f2642cd5 100644 --- a/test/browser/browser.test.js +++ b/test/browser/browser.test.js @@ -2345,6 +2345,43 @@ describe('browser', () => { assert.strictEqual(netErrs.name, 'ResponseTimeoutError'); store.urllib.request.restore(); }); + + it('should normal processing of non-OSS errors', async () => { + const stubNetError = sinon.stub(store.urllib, 'request'); + const netErr = new Error('TestNonOSSErrorException'); + netErr.status = 400; + netErr.code = 'TestNonOSSError'; + stubNetError.throws(netErr); + let nonOSSErr; + try { + await store.head('test.txt'); + assert.fail('Expect to throw an error.'); + } catch (err) { + nonOSSErr = err; + } + + assert.strictEqual(nonOSSErr.message, `Unknow error, status: ${netErr.status}`); + assert.strictEqual(nonOSSErr.name, 'UnknownError'); + assert.strictEqual(nonOSSErr.status, netErr.status); + stubNetError.restore(); + + nonOSSErr = undefined; + const stubNetError2 = sinon.stub(store.urllib, 'request'); + const netErr2 = new Error('TestNonOSSErrorException'); + netErr2.status = 400; + netErr2.data = 'TestNonOSSError'; + stubNetError2.throws(netErr2); + try { + await store.getBucketACL('test'); + assert.fail('Expect to throw an error.'); + } catch (err) { + nonOSSErr = err; + } + + assert(nonOSSErr.message.includes(`\nraw xml: ${netErr2.data}`)); + assert.strictEqual(nonOSSErr.status, netErr2.status); + stubNetError2.restore(); + }); }); describe('options.headerEncoding', () => { diff --git a/test/node/multipart.test.js b/test/node/multipart.test.js index 8d52b1d1..0665359f 100644 --- a/test/node/multipart.test.js +++ b/test/node/multipart.test.js @@ -688,6 +688,43 @@ describe('test/multipart.test.js', () => { assert.strictEqual(netErrs.name, 'abort'); store._uploadPart.restore(); }); + + it('should normal processing of non-OSS errors', async () => { + const stubNetError = sinon.stub(store.urllib, 'request'); + const netErr = new Error('TestNonOSSErrorException'); + netErr.status = 400; + netErr.code = 'TestNonOSSError'; + stubNetError.throws(netErr); + let nonOSSErr; + try { + await store.head('test.txt'); + assert.fail('Expect to throw an error.'); + } catch (err) { + nonOSSErr = err; + } + + assert.strictEqual(nonOSSErr.message, `Unknow error, status: ${netErr.status}`); + assert.strictEqual(nonOSSErr.name, 'UnknownError'); + assert.strictEqual(nonOSSErr.status, netErr.status); + stubNetError.restore(); + + nonOSSErr = undefined; + const stubNetError2 = sinon.stub(store.urllib, 'request'); + const netErr2 = new Error('TestNonOSSErrorException'); + netErr2.status = 400; + netErr2.data = 'TestNonOSSError'; + stubNetError2.throws(netErr2); + try { + await store.listBuckets(); + assert.fail('Expect to throw an error.'); + } catch (err) { + nonOSSErr = err; + } + + assert(nonOSSErr.message.includes(`\nraw xml: ${netErr2.data}`)); + assert.strictEqual(nonOSSErr.status, netErr2.status); + stubNetError2.restore(); + }); }); describe('multipartCopy()', () => { diff --git a/test/node/rtmp.test.js b/test/node/rtmp.test.js index 57e6b480..d7b0666e 100644 --- a/test/node/rtmp.test.js +++ b/test/node/rtmp.test.js @@ -42,7 +42,7 @@ describe('test/rtmp.test.js', () => { ].forEach((moreConfigs, index) => { describe(`test rtmp in iterate ${index}`, () => { before(async () => { - store = oss(config); + store = oss({ ...config, ...moreConfigs }); bucket = `ali-oss-test-bucket-rtmp-${prefix.replace(/[/.]/g, '-')}${index}`; store.useBucket(bucket);