Socket
Socket
Sign inDemoInstall

bestbuy

Package Overview
Dependencies
Maintainers
3
Versions
19
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

bestbuy - npm Package Compare versions

Comparing version 2.2.0 to 2.3.0

.npmignore

4

CHANGELOG.md

@@ -0,1 +1,5 @@

## 2.3.0 (2020-02-14)
- Change emitted error format—errors now have `headers`, `status`, `body`, and `cause` keys.
- Always emit errors when `maxRetries` is exhausted during streaming.
## 2.2.0 (2020-01-29)

@@ -2,0 +6,0 @@ - Add `maxRetries` and `retryInterval` configuration options.

6

examples/products.js

@@ -20,6 +20,4 @@ // Initialize with your Best Buy developer API key - if it is present as a

console.log('Here is what an error looks like:');
console.log('HTTP Status Code: ' + err.statusCode);
console.log(err.message);
console.log('There are %d examples of how to do it right',
err.error.error.examples.length);
console.log('HTTP Status Code: ' + err.status);
console.log('Response body: ' + JSON.stringify(err.body));
console.log('');

@@ -26,0 +24,0 @@ });

@@ -28,3 +28,3 @@ module.exports = apiServiceFactory;

if (attempts > opts.maxRetries) {
return finishWithError(error, callback);
return finishWithError(error, request.params.format, callback);
}

@@ -40,12 +40,53 @@

return finishWithError(error, callback);
return finishWithError(error, request.params.format, callback);
});
}
function finishWithError (error, callback) {
if (callback) callback(error.response);
if (error.response) return Promise.reject(error.response);
return Promise.reject(error);
function finishWithError (error, requestFormat, callback) {
const wrappingError = new Error('Exceeded max retries');
const response = error.response;
if (response) {
wrappingError.headers = response.headers;
wrappingError.status = response.status;
if (response.data.constructor.name === 'IncomingMessage') {
return getBodyFromStream(response.data)
.then(body => {
wrappingError.body = requestFormat === 'json' ? JSON.parse(body) : body;
return wrappingError;
})
.catch(error => {
wrappingError.errorHandlingError = error;
return wrappingError;
})
.then(wrappingError => {
if (callback) callback(wrappingError);
throw wrappingError;
});
} else {
wrappingError.body = response.data;
}
}
if (callback) {
callback(wrappingError);
} else {
return Promise.reject(wrappingError);
}
}
function getBodyFromStream (s) {
return new Promise((resolve, reject) => {
let body = '';
s.on('readable', () => {
const read = s.read();
if (read) body += read;
});
s.on('error', error => {
reject(error);
});
s.on('end', () => {
resolve(body);
});
});
}
function waitABit (ms) {

@@ -52,0 +93,0 @@ return new Promise(resolve => {

@@ -74,11 +74,4 @@ module.exports = apiStreamJsonServiceFactory;

.catch(error => {
var errorStream = JSONStream.parse('*.message');
errorStream.on('data', msg => {
stream.emit('error', new Error(msg));
});
pump(error.data, errorStream, (err) => {
if (err) console.error(err);
stream.end();
});
stream.emit('error', error);
stream.end();
});

@@ -85,0 +78,0 @@ }

@@ -82,11 +82,4 @@ module.exports = apiStreamXmlServiceFactory;

.catch(error => {
var errorStream = xmlNodes('error');
errorStream.on('data', msg => {
stream.emit('error', new Error(msg));
});
pump(error.data, errorStream, (err) => {
if (err) console.error(err);
stream.end();
});
stream.emit('error', error);
stream.end();
});

@@ -93,0 +86,0 @@ }

@@ -11,4 +11,4 @@ module.exports = availabilityEndpoint;

}
if (typeof callback === 'undefined') callback = function noop () {};
if (typeof callback !== 'function') {
if (typeof callback !== 'function' && typeof callback !== 'undefined') {
var argsErr = new Error('Unrecognized parameter length when calling "availability" method');

@@ -22,3 +22,5 @@ return Promise.reject(argsErr);

} catch (err) {
callback(err);
if (callback) {
callback(err);
}
return Promise.reject(err);

@@ -25,0 +27,0 @@ }

@@ -11,3 +11,2 @@ module.exports = categoriesEndpoint;

}
if (typeof callback === 'undefined') callback = function noop () {};

@@ -14,0 +13,0 @@ return opts.apiService(prepareRequest(search, params), callback);

@@ -11,3 +11,2 @@ module.exports = openBoxEndpoint;

}
if (typeof callback === 'undefined') callback = function noop () {};

@@ -14,0 +13,0 @@ return opts.apiService(prepareRequest(search, params), callback);

@@ -12,4 +12,2 @@ module.exports = productsEndpoint;

if (typeof callback === 'undefined') callback = function noop () {};
if (typeof params === 'function') {

@@ -16,0 +14,0 @@ var queryObjFuncErr = new Error('Unhandled parameter type');

@@ -7,7 +7,7 @@ module.exports = realTimeAvailabilityEndpoint;

function realTimeAvailability (sku, params, callback) {
if (typeof callback === 'undefined') callback = function noop () {};
if (!(params.storeId || params.postalCode)) {
var argsErr = new Error('Must provide either storeId or postalCode');
callback(argsErr);
if (callback) {
callback(argsErr);
}
return Promise.reject(argsErr);

@@ -20,3 +20,5 @@ }

} catch (err) {
callback(err);
if (callback) {
callback(err);
}
return Promise.reject(err);

@@ -23,0 +25,0 @@ }

@@ -9,3 +9,2 @@ module.exports = recommendationsEndpoint;

}
if (typeof callback === 'undefined') callback = function noop () {};

@@ -17,3 +16,5 @@ var url;

var criteriaErr = new Error('Recommendations endpoint requires 2nd parameter to be a SKU for the "' + path + '" method');
callback(criteriaErr);
if (callback) {
callback(criteriaErr);
}
return Promise.reject(criteriaErr);

@@ -25,3 +26,5 @@ }

var criteriaFuncErr = new Error('Unhandled parameter type');
callback(criteriaFuncErr);
if (callback) {
callback(criteriaFuncErr);
}
return Promise.reject(criteriaFuncErr);

@@ -32,3 +35,5 @@ }

var pathErr = new Error(`Unrecognized path "${path}"`);
callback(pathErr);
if (callback) {
callback(pathErr);
}
return Promise.reject(pathErr);

@@ -35,0 +40,0 @@ }

@@ -12,4 +12,2 @@ module.exports = storesEndpoint;

if (typeof callback === 'undefined') callback = function noop () {};
return opts.apiService(prepareRequest(search, params), callback);

@@ -16,0 +14,0 @@ }

@@ -7,7 +7,6 @@ module.exports = versionEndpoint;

return function version (callback) {
if (typeof callback === 'undefined') callback = function noop () {};
var url = `${opts.url}/version.txt`;
const jsonifiedCallback = callback ? jsonify(callback) : undefined;
return opts.apiService({url}, jsonify(callback))
return opts.apiService({url}, jsonifiedCallback)
.then(version => {

@@ -14,0 +13,0 @@ return createVersionObject(version);

@@ -5,4 +5,2 @@ module.exports = warrantiesEndpoint;

return function warranties (sku, callback) {
if (typeof callback === 'undefined') callback = function noop () {};
var url = `${opts.url}/v1/products/${sku}/warranties.json`;

@@ -9,0 +7,0 @@

{
"name": "bestbuy",
"version": "2.2.0",
"version": "2.3.0",
"description": "High level node.js client for the Best Buy API.",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -70,2 +70,3 @@ # Best Buy API

- a `data` event will be emitted for each item in the result (one per product/store/etc).
- an `error` event will be emitted once `maxRetries` is exceeded.

@@ -103,3 +104,8 @@ ### availability

});
stream.on('error', function (error) {
console.error(`Error status: ${error.status}`);
console.error(`Error headers: ${error.headers}`);
console.error(`Error body: ${error.body}`);
console.error(`Error cause: ${error.cause}`);
})
```

@@ -106,0 +112,0 @@

@@ -80,2 +80,3 @@ var test = require('./lib/tape-nock-setup');

t.equals(error.status, 400, 'error code 400 returned');
t.ok(error.body.error, 'error element present');
t.end();

@@ -88,4 +89,5 @@ });

bby.products('gurgleflats')
.catch(function (data) {
t.equals(data.status, 400, 'status 400 returned');
.catch(function (error) {
t.equals(error.status, 400, 'status 400 returned');
t.ok(error.body.error, 'error element present');
t.end();

@@ -99,2 +101,3 @@ });

t.equals(err.status, 400, 'status 400 returned');
t.ok(err.body.error, 'error element present');
t.end();

@@ -211,10 +214,18 @@ });

test('Is a garbage search as xml stream', test.opts, function (t) {
// Do a search which emits an error
var stream = bby.productsAsStream('gurgleflats', {format: 'xml'});
test('Handles garbage search with xml stream', test.opts, function (t) {
const stream = bby.productsAsStream('gurgleflats', {format: 'xml'});
stream.on('error', err => {
t.equals(err.status, 400, 'returns response status');
t.ok(err.body.indexOf('<error') > -1, 'error element present');
t.end();
});
});
test('Handles garbage search with json stream', test.opts, function (t) {
const stream = bby.productsAsStream('gurgleflats', {format: 'json'});
stream.on('error', err => {
t.ok(err.toString().indexOf('<error') > -1, 'error element present');
t.equals(err.status, 400, 'returns response status');
t.ok(err.body.error, 'error element present');
t.end();
});
});

@@ -132,5 +132,5 @@ var test = require('./lib/tape-nock-setup');

stream.on('error', (err) => {
t.ok(err.message.startsWith("Couldn't understand"), 'error returned');
t.ok(err.body.error.message.startsWith("Couldn't understand"), 'error returned');
t.end();
});
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc