@contentstack/datasync-manager 2.1.1 → 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api.js +40 -9
- package/dist/config.js +2 -0
- package/dist/core/inet.js +4 -1
- package/package.json +1 -1
package/dist/api.js
CHANGED
|
@@ -17,11 +17,13 @@ const sanitize_url_1 = require("@braintree/sanitize-url");
|
|
|
17
17
|
const fs_1 = require("./util/fs");
|
|
18
18
|
const debug = (0, debug_1.default)('api');
|
|
19
19
|
let MAX_RETRY_LIMIT;
|
|
20
|
+
let RETRY_DELAY_BASE = 200; // Default base delay in milliseconds
|
|
21
|
+
let TIMEOUT = 30000; // Default timeout in milliseconds
|
|
20
22
|
let Contentstack;
|
|
21
23
|
/**
|
|
22
24
|
* @description Initialize sync utilities API requests
|
|
23
25
|
* @param {Object} contentstack - Contentstack configuration details
|
|
24
|
-
|
|
26
|
+
*/
|
|
25
27
|
const init = (contentstack) => {
|
|
26
28
|
const packageInfo = JSON.parse((0, fs_1.readFileSync)((0, path_1.join)(__dirname, '..', 'package.json')));
|
|
27
29
|
Contentstack = contentstack;
|
|
@@ -36,6 +38,12 @@ const init = (contentstack) => {
|
|
|
36
38
|
if (Contentstack.MAX_RETRY_LIMIT) {
|
|
37
39
|
MAX_RETRY_LIMIT = Contentstack.MAX_RETRY_LIMIT;
|
|
38
40
|
}
|
|
41
|
+
if (Contentstack.RETRY_DELAY_BASE) {
|
|
42
|
+
RETRY_DELAY_BASE = Contentstack.RETRY_DELAY_BASE;
|
|
43
|
+
}
|
|
44
|
+
if (Contentstack.TIMEOUT) {
|
|
45
|
+
TIMEOUT = Contentstack.TIMEOUT;
|
|
46
|
+
}
|
|
39
47
|
};
|
|
40
48
|
exports.init = init;
|
|
41
49
|
/**
|
|
@@ -60,12 +68,13 @@ const get = (req, RETRY = 1) => {
|
|
|
60
68
|
path: (0, sanitize_url_1.sanitizeUrl)(encodeURI(req.path)),
|
|
61
69
|
port: Contentstack.port,
|
|
62
70
|
protocol: Contentstack.protocol,
|
|
71
|
+
timeout: TIMEOUT, // Configurable timeout to prevent socket hang ups
|
|
63
72
|
};
|
|
64
73
|
try {
|
|
65
74
|
debug(`${options.method.toUpperCase()}: ${options.path}`);
|
|
66
75
|
let timeDelay;
|
|
67
76
|
let body = '';
|
|
68
|
-
(0, https_1.request)(options, (response) => {
|
|
77
|
+
const httpRequest = (0, https_1.request)(options, (response) => {
|
|
69
78
|
response
|
|
70
79
|
.setEncoding('utf-8')
|
|
71
80
|
.on('data', (chunk) => body += chunk)
|
|
@@ -75,8 +84,8 @@ const get = (req, RETRY = 1) => {
|
|
|
75
84
|
return resolve(JSON.parse(body));
|
|
76
85
|
}
|
|
77
86
|
else if (response.statusCode === 429) {
|
|
78
|
-
timeDelay = Math.pow(Math.SQRT2, RETRY) *
|
|
79
|
-
debug(`API rate limit exceeded. Retrying ${options.path} with ${timeDelay}
|
|
87
|
+
timeDelay = Math.pow(Math.SQRT2, RETRY) * RETRY_DELAY_BASE;
|
|
88
|
+
debug(`API rate limit exceeded. Retrying ${options.path} with ${timeDelay} ms delay`);
|
|
80
89
|
return setTimeout(() => {
|
|
81
90
|
return (0, exports.get)(req, RETRY)
|
|
82
91
|
.then(resolve)
|
|
@@ -85,8 +94,8 @@ const get = (req, RETRY = 1) => {
|
|
|
85
94
|
}
|
|
86
95
|
else if (response.statusCode >= 500) {
|
|
87
96
|
// retry, with delay
|
|
88
|
-
timeDelay = Math.pow(Math.SQRT2, RETRY) *
|
|
89
|
-
debug(`Retrying ${options.path} with ${timeDelay}
|
|
97
|
+
timeDelay = Math.pow(Math.SQRT2, RETRY) * RETRY_DELAY_BASE;
|
|
98
|
+
debug(`Retrying ${options.path} with ${timeDelay} ms delay`);
|
|
90
99
|
RETRY++;
|
|
91
100
|
return setTimeout(() => {
|
|
92
101
|
return (0, exports.get)(req, RETRY)
|
|
@@ -99,9 +108,31 @@ const get = (req, RETRY = 1) => {
|
|
|
99
108
|
return reject(body);
|
|
100
109
|
}
|
|
101
110
|
});
|
|
102
|
-
})
|
|
103
|
-
|
|
104
|
-
|
|
111
|
+
});
|
|
112
|
+
// Set socket timeout to handle socket hang ups
|
|
113
|
+
httpRequest.setTimeout(options.timeout, () => {
|
|
114
|
+
debug(`Request timeout for ${options.path || 'unknown'}`);
|
|
115
|
+
httpRequest.destroy();
|
|
116
|
+
reject(new Error('Request timeout'));
|
|
117
|
+
});
|
|
118
|
+
// Enhanced error handling for socket hang ups and connection resets
|
|
119
|
+
httpRequest.on('error', (error) => {
|
|
120
|
+
var _a;
|
|
121
|
+
debug(`Request error for ${options.path || 'unknown'}: ${(error === null || error === void 0 ? void 0 : error.message) || 'Unknown error'} (${(error === null || error === void 0 ? void 0 : error.code) || 'NO_CODE'})`);
|
|
122
|
+
// Handle socket hang up and connection reset errors with retry
|
|
123
|
+
if (((error === null || error === void 0 ? void 0 : error.code) === 'ECONNRESET' || ((_a = error === null || error === void 0 ? void 0 : error.message) === null || _a === void 0 ? void 0 : _a.includes('socket hang up'))) && RETRY <= MAX_RETRY_LIMIT) {
|
|
124
|
+
timeDelay = Math.pow(Math.SQRT2, RETRY) * RETRY_DELAY_BASE;
|
|
125
|
+
debug(`Socket hang up detected. Retrying ${options.path || 'unknown'} with ${timeDelay} ms delay (attempt ${RETRY}/${MAX_RETRY_LIMIT})`);
|
|
126
|
+
RETRY++;
|
|
127
|
+
return setTimeout(() => {
|
|
128
|
+
return (0, exports.get)(req, RETRY)
|
|
129
|
+
.then(resolve)
|
|
130
|
+
.catch(reject);
|
|
131
|
+
}, timeDelay);
|
|
132
|
+
}
|
|
133
|
+
return reject(error);
|
|
134
|
+
});
|
|
135
|
+
httpRequest.end();
|
|
105
136
|
}
|
|
106
137
|
catch (error) {
|
|
107
138
|
return reject(error);
|
package/dist/config.js
CHANGED
package/dist/core/inet.js
CHANGED
|
@@ -68,7 +68,10 @@ const checkNetConnectivity = () => {
|
|
|
68
68
|
};
|
|
69
69
|
exports.checkNetConnectivity = checkNetConnectivity;
|
|
70
70
|
const netConnectivityIssues = (error) => {
|
|
71
|
-
|
|
71
|
+
var _a;
|
|
72
|
+
// Include socket hang up and connection reset errors as network connectivity issues
|
|
73
|
+
const networkErrorCodes = ['ENOTFOUND', 'ETIMEDOUT', 'ECONNRESET', 'EPIPE', 'EHOSTUNREACH'];
|
|
74
|
+
if (networkErrorCodes.includes(error.code) || ((_a = error.message) === null || _a === void 0 ? void 0 : _a.includes('socket hang up'))) {
|
|
72
75
|
return true;
|
|
73
76
|
}
|
|
74
77
|
return false;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentstack/datasync-manager",
|
|
3
3
|
"author": "Contentstack LLC <support@contentstack.com>",
|
|
4
|
-
"version": "2.1.
|
|
4
|
+
"version": "2.1.2",
|
|
5
5
|
"description": "The primary module of Contentstack DataSync. Syncs Contentstack data with your server using Contentstack Sync API",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"dependencies": {
|