From 52a5d349f469d79b201ca73cd944d5bd90d48d10 Mon Sep 17 00:00:00 2001 From: richardkeller411 Date: Sat, 14 Sep 2019 08:44:59 -0700 Subject: [PATCH] Fix the Error Body lack of Decompression --- lib/request.js | 69 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 55 insertions(+), 14 deletions(-) diff --git a/lib/request.js b/lib/request.js index 739c294..63e30b7 100644 --- a/lib/request.js +++ b/lib/request.js @@ -15,7 +15,10 @@ const { version } = require('../package.json'); */ function parseResponse(res, body, resolve, reject) { try { - if (!/application\/json/.test(res.headers['content-type']) || body.trim() === '') { + if ( + !/application\/json/.test(res.headers['content-type']) || + body.trim() === '' + ) { return resolve(body); } @@ -35,8 +38,15 @@ function parseResponse(res, body, resolve, reject) { } class Request { - constructor(hostname, { headers = { }, failOnLimitReached = false, agent = null } = { }) { - if (!hostname) throw new Error('The hostname is required to make the call to the server.'); + constructor( + hostname, + { headers = {}, failOnLimitReached = false, agent = null } = {} + ) { + if (!hostname) { + throw new Error( + 'The hostname is required to make the call to the server.' + ); + } this.hostname = hostname; this.headers = headers; @@ -45,7 +55,9 @@ class Request { } run(method, path, data) { - logger(`Requesting Data from: https://${this.hostname}${path} Using the ${method} method`); + logger( + `Requesting Data from: https://${this.hostname}${path} Using the ${method} method` + ); const dataString = JSON.stringify(data); @@ -54,11 +66,14 @@ class Request { hostname: this.hostname, method: method.toUpperCase(), port: 443, - headers: Object.assign({ - 'User-Agent': 'node-bigcommerce/' + version, - 'Content-Type': 'application/json', - 'Accept-Encoding': 'gzip, deflate' - }, this.headers) + headers: Object.assign( + { + 'User-Agent': 'node-bigcommerce/' + version, + 'Content-Type': 'application/json', + 'Accept-Encoding': 'gzip, deflate' + }, + this.headers + ) }; if (this.agent) options.agent = this.agent; @@ -86,13 +101,17 @@ class Request { const timeToWait = res.headers['x-retry-after']; if (this.failOnLimitReached) { - const err = new Error(`You have reached the rate limit for the BigCommerce API. Please retry in ${timeToWait} seconds.`); + const err = new Error( + `You have reached the rate limit for the BigCommerce API. Please retry in ${timeToWait} seconds.` + ); err.retryAfter = Number(timeToWait); return reject(err); } - logger(`You have reached the rate limit for the BigCommerce API, we will retry again in ${timeToWait} seconds.`); + logger( + `You have reached the rate limit for the BigCommerce API, we will retry again in ${timeToWait} seconds.` + ); return setTimeout(() => { logger('Restarting request call after suggested time'); @@ -103,13 +122,34 @@ class Request { }, timeToWait * 1000); } - res.on('data', chunk => body += chunk); + res.on('data', chunk => (body += chunk)); res.on('end', () => { logger('Request complete'); if (res.statusCode >= 400 && res.statusCode <= 600) { - const error = new Error(`Request returned error code: ${res.statusCode} and body: ${body}`); + if (shouldUnzip) { + const unzip = + contentEncoding === 'deflate' ? zlib.deflate : zlib.gunzip; + return unzip(Buffer.from(body, encoding), (err, data) => { + if (err) { + return reject(err); + } + + const error = new Error( + `Request returned error code: ${ + res.statusCode + } and body: ${data.toString('utf8')}` + ); + error.code = res.statusCode; + error.responseBody = data.toString('utf8'); + return reject(error); + }); + } + + const error = new Error( + `Request returned error code: ${res.statusCode} and body: ${body}` + ); error.code = res.statusCode; error.responseBody = body; @@ -118,7 +158,8 @@ class Request { // Use GZIP decompression if required if (shouldUnzip) { - const unzip = contentEncoding === 'deflate' ? zlib.deflate : zlib.gunzip; + const unzip = + contentEncoding === 'deflate' ? zlib.deflate : zlib.gunzip; return unzip(Buffer.from(body, encoding), (err, data) => { if (err) { return reject(err);