Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@jsforce/jsforce-node

Package Overview
Dependencies
Maintainers
1
Versions
25
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@jsforce/jsforce-node - npm Package Compare versions

Comparing version 3.1.0 to 3.2.0

111

lib/request.js
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {

@@ -8,3 +31,3 @@ return (mod && mod.__esModule) ? mod : { "default": mod };

const stream_1 = require("stream");
const node_fetch_1 = __importDefault(require("node-fetch"));
const node_fetch_1 = __importStar(require("node-fetch"));
const abort_controller_1 = __importDefault(require("abort-controller"));

@@ -37,3 +60,6 @@ const https_proxy_agent_1 = __importDefault(require("https-proxy-agent"));

const retryOpts = {
statusCodes: options.retry?.statusCodes ?? [429, 500, 502, 503, 504],
maxRetries: options.retry?.maxRetries ?? 5,
minTimeout: options.retry?.minTimeout ?? 500,
timeoutFactor: options.retry?.timeoutFactor ?? 2,
errorCodes: options.retry?.errorCodes ?? [

@@ -58,2 +84,36 @@ 'ECONNRESET',

};
const shouldRetryRequest = (maxRetry, resOrErr) => {
if (!retryOpts.methods.includes(request.method))
return false;
if (resOrErr instanceof node_fetch_1.Response) {
if (retryOpts.statusCodes.includes(resOrErr.status)) {
if (maxRetry === retryCount) {
const err = new Error('Request failed');
err.name = 'RequestRetryError';
throw err;
}
else {
return true;
}
}
return false;
}
else {
if (maxRetry === retryCount)
return false;
// only retry on operational errors
// https://github.com/node-fetch/node-fetch/blob/2.x/ERROR-HANDLING.md#error-handling-with-node-fetch
if (resOrErr.name != 'FetchError')
return false;
if (is_1.default.nodeStream(body) && stream_1.Readable.isDisturbed(body)) {
logger.debug('Body of type stream was read, unable to retry request.');
return false;
}
if ('code' in resOrErr &&
resOrErr.code &&
retryOpts?.errorCodes?.includes(resOrErr.code))
return true;
return false;
}
};
const fetchWithRetries = async (maxRetry = retryOpts?.maxRetries) => {

@@ -70,3 +130,17 @@ const fetchOpts = {

try {
return await (0, node_fetch_1.default)(url, fetchOpts);
const res = await (0, node_fetch_1.default)(url, fetchOpts);
if (shouldRetryRequest(retryOpts.maxRetries, res)) {
logger.debug(`retrying for the ${retryCount + 1} time`);
logger.debug(`reason: statusCode match`);
await sleep(retryCount === 0
? retryOpts.minTimeout
: retryOpts.minTimeout * retryOpts.timeoutFactor ** retryCount);
// NOTE: this event is only used by tests and will be removed at any time.
// jsforce may switch to node's fetch which doesn't emit this event on retries.
emitter.emit('retry', retryCount);
retryCount++;
return await fetchWithRetries(maxRetry);
}
// should we throw here if the maxRetry already happened and still got the same statusCode?
return res;
}

@@ -80,23 +154,8 @@ catch (err) {

}
const shouldRetry = () => {
// only retry on operational errors
if (error.name != 'FetchError')
return false;
if (retryCount === maxRetry)
return false;
if (!retryOpts?.methods?.includes(request.method))
return false;
if (is_1.default.nodeStream(body) && stream_1.Readable.isDisturbed(body)) {
logger.debug('Body of type stream was read, unable to retry request.');
return false;
}
if ('code' in error &&
error.code &&
retryOpts?.errorCodes?.includes(error.code))
return true;
return false;
};
if (shouldRetry()) {
if (shouldRetryRequest(retryOpts.maxRetries, error)) {
logger.debug(`retrying for the ${retryCount + 1} time`);
logger.debug(`Error: ${error}`);
await sleep(retryCount === 0
? retryOpts.minTimeout
: retryOpts.minTimeout * retryOpts.timeoutFactor ** retryCount);
// NOTE: this event is only used by tests and will be removed at any time.

@@ -109,3 +168,10 @@ // jsforce may switch to node's fetch which doesn't emit this event on retries.

logger.debug('Skipping retry...');
throw err;
if (maxRetry === retryCount) {
const error = new Error('Request failed', { cause: err });
error.name = 'RequestRetryError';
throw error;
}
else {
throw err;
}
}

@@ -151,1 +217,2 @@ };

exports.default = request;
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));

@@ -24,4 +24,7 @@ /// <reference types="node" />

maxRetries?: number;
minTimeout?: number;
timeoutFactor?: number;
errorCodes?: string[];
methods?: HttpMethods[];
statusCodes?: number[];
};

@@ -28,0 +31,0 @@ httpProxy?: string;

2

package.json

@@ -13,3 +13,3 @@ {

"homepage": "http://github.com/jsforce/jsforce",
"version": "3.1.0",
"version": "3.2.0",
"repository": {

@@ -16,0 +16,0 @@ "type": "git",

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