@mimik/request-retry 1.0.1 → 2.0.8
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/.eslintrc +17 -5
- package/.husky/pre-commit +4 -0
- package/.husky/pre-push +4 -0
- package/README.md +11 -3
- package/index.js +68 -26
- package/lib/rp-axios-wrapper.js +48 -0
- package/lib/validate.js +11 -11
- package/manual-test/httpMock.js +16 -0
- package/manual-test/man.js +23 -0
- package/manual-test/retryMockMan.js +60 -0
- package/manual-test/testRace.js +20 -19
- package/manual-test/testRetry.js +44 -42
- package/package.json +36 -35
- package/test/retryMock.js +8 -0
- package/test/rpRetry.spec.js +26 -16
- package/test/testEnv.js +18 -2
- package/Gulpfile.js +0 -42
- package/package.json.bak +0 -60
package/.eslintrc
CHANGED
|
@@ -1,21 +1,33 @@
|
|
|
1
|
-
// Use this file as a starting point for your project's .eslintrc.
|
|
2
|
-
// Copy this file, and add rule overrides as needed.
|
|
3
1
|
{
|
|
2
|
+
"plugins": [
|
|
3
|
+
"@mimik/document-env",
|
|
4
|
+
"@mimik/dependencies"
|
|
5
|
+
],
|
|
4
6
|
"env": {
|
|
5
7
|
"node": true
|
|
6
8
|
},
|
|
9
|
+
"parserOptions": {
|
|
10
|
+
"ecmaVersion": 2020
|
|
11
|
+
},
|
|
7
12
|
"extends": "airbnb",
|
|
8
13
|
"rules": {
|
|
14
|
+
"import/no-extraneous-dependencies": ["error", {"devDependencies": true}],
|
|
15
|
+
"import/no-unresolved": ["error", { "amd": true, "commonjs": true, "caseSensitiveStrict": true }],
|
|
9
16
|
"brace-style": [1, "stroustrup", {"allowSingleLine": true}],
|
|
10
|
-
"no-confusing-arrow": [0],
|
|
17
|
+
"no-confusing-arrow": [0], // arrow isnt confusing
|
|
11
18
|
"max-len": [1, 180, { "ignoreComments": true }],
|
|
12
19
|
"linebreak-style": 0,
|
|
13
20
|
"quotes": [1, "single"],
|
|
14
|
-
"semi": [1, "always"]
|
|
21
|
+
"semi": [1, "always"],
|
|
22
|
+
"no-process-env": ["error"],
|
|
23
|
+
"@mimik/document-env/validate-document-env": 2,
|
|
24
|
+
"@mimik/dependencies/case-sensitive": 2,
|
|
25
|
+
"@mimik/dependencies/no-cycles": 2,
|
|
26
|
+
"@mimik/dependencies/require-json-ext": 2
|
|
15
27
|
},
|
|
16
28
|
"settings":{
|
|
17
29
|
"react": {
|
|
18
|
-
"version": "
|
|
30
|
+
"version": "detect"
|
|
19
31
|
}
|
|
20
32
|
},
|
|
21
33
|
"globals": {
|
package/.husky/pre-push
ADDED
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@ Make a request with retry.
|
|
|
15
15
|
**Category**: async
|
|
16
16
|
**Throws**:
|
|
17
17
|
|
|
18
|
-
- <code>Promise</code> Will throw an error generated by getRichError encapsulating an error generated by [request-promise](https://www.npmjs.com/package/request-promise) or a TimeoutError.
|
|
18
|
+
- <code>Promise</code> Will throw an error generated by `getRichError` encapsulating an error generated by [request-promise](https://www.npmjs.com/package/request-promise) or a TimeoutError.
|
|
19
19
|
|
|
20
20
|
The following properties are added to the `options` object under the `retry` property:
|
|
21
21
|
- retries `{int}`: maximum number of retries independent to the retryStrategy. The default is `2`. If the value is less than `0` the value is set to `0`, and if the value is more that `15` the value is set to `15`,
|
|
@@ -38,11 +38,19 @@ defaultRetry = (...args) => {
|
|
|
38
38
|
return (statusCode && (Math.floor(statusCode / 100) === 5 || statusCode === 429)) || (!statusCode && !args[1].message.includes('Invalid URI'));
|
|
39
39
|
};
|
|
40
40
|
```
|
|
41
|
+
If logLevel is empty, request and response will be logged as info and the response will be in response property with full details. Error on the request will generate a warning. If logLevel is not empty but not complete, logLevel will take control over default.
|
|
42
|
+
|
|
43
|
+
If not alredy set,the user agent will the set to `mimik-{serverType}/{serverVersion}/{serverId} {architecture} {node}`;
|
|
44
|
+
|
|
45
|
+
To facilitate the transition from request-promise the following action are taken on options:
|
|
46
|
+
- `uri` takes precednce on `url`
|
|
47
|
+
- `body` takes precedence on `json` if `json` is an object and are used to assign `data`
|
|
48
|
+
- `qs` is used to assign to `params`
|
|
41
49
|
|
|
42
50
|
**Requires**: <code>module:@mimik/sumologic-winston-logger</code>, <code>module:@mimik/response-helper</code>
|
|
43
|
-
**Fulfil**: <code>object</code> - Response of the [
|
|
51
|
+
**Fulfil**: <code>object</code> - Response of the [axios](https://www.npmjs.com/package/axios) response with option `resolveWithFullResponse` set to true otherwise only `response.data` is returned.
|
|
44
52
|
|
|
45
53
|
| Param | Type | Description |
|
|
46
54
|
| --- | --- | --- |
|
|
47
|
-
| options | <code>object</code> | Options for the request. Similar to [
|
|
55
|
+
| options | <code>object</code> | Options for the request. Similar to [axios](https://www.npmjs.com/package/axios) options. `validateStatus` options is disabled, an error will be created for statusCode outside of [200, 300[. The options `resolveWithFullResponse` is added and if set to true, the response will be a full axios response. If set to false or missing only `reponse.data` will be returned. |
|
|
48
56
|
|
package/index.js
CHANGED
|
@@ -1,15 +1,22 @@
|
|
|
1
|
-
const rp = require('request-promise');
|
|
2
1
|
const Promise = require('bluebird');
|
|
2
|
+
const axios = require('axios');
|
|
3
3
|
|
|
4
4
|
const logger = require('@mimik/sumologic-winston-logger');
|
|
5
5
|
const { getRichError } = require('@mimik/response-helper');
|
|
6
|
-
|
|
6
|
+
const { getCorrelationId, getUserAgent } = require('@mimik/request-helper');
|
|
7
7
|
const {
|
|
8
8
|
validateOptions,
|
|
9
9
|
calculateDelay,
|
|
10
10
|
isRetry,
|
|
11
11
|
setResponse,
|
|
12
12
|
} = require('./lib/validate');
|
|
13
|
+
const { rp } = require('./lib/rp-axios-wrapper');
|
|
14
|
+
|
|
15
|
+
const DEFAULT_RESPONSE_NAME = 'response';
|
|
16
|
+
const DEFAULT_LOGLEVEL_DETAILS = 'full';
|
|
17
|
+
const DEFAULT_LOGLEVEL_RESPONSE = 'info';
|
|
18
|
+
const DEFAULT_LOGLEVEL_ERROR = 'warn';
|
|
19
|
+
const DEFAULT_LOGLEVEL_REQUEST = 'info';
|
|
13
20
|
|
|
14
21
|
Promise.config({ cancellation: true });
|
|
15
22
|
|
|
@@ -26,10 +33,10 @@ Promise.config({ cancellation: true });
|
|
|
26
33
|
* @requires @mimik/sumologic-winston-logger
|
|
27
34
|
* @requires @mimik/response-helper
|
|
28
35
|
* @category async
|
|
29
|
-
* @param {object} options - Options for the request. Similar to [
|
|
36
|
+
* @param {object} options - Options for the request. Similar to [axios](https://www.npmjs.com/package/axios) options. `validateStatus` options is disabled, an error will be created for statusCode outside of [200, 300[. The options `resolveWithFullResponse` is added and if set to true, the response will be a full axios response. If set to false or missing only `reponse.data` will be returned.
|
|
30
37
|
* @return {Promise}.
|
|
31
|
-
* @fulfil {object} - Response of the [
|
|
32
|
-
* @throws {Promise} Will throw an error generated by getRichError encapsulating an error generated by [request-promise](https://www.npmjs.com/package/request-promise) or a TimeoutError.
|
|
38
|
+
* @fulfil {object} - Response of the [axios](https://www.npmjs.com/package/axios) response with option `resolveWithFullResponse` set to true otherwise only `response.data` is returned.
|
|
39
|
+
* @throws {Promise} Will throw an error generated by `getRichError` encapsulating an error generated by [request-promise](https://www.npmjs.com/package/request-promise) or a TimeoutError.
|
|
33
40
|
*
|
|
34
41
|
* The following properties are added to the `options` object under the `retry` property:
|
|
35
42
|
* - retries `{int}`: maximum number of retries independent to the retryStrategy. The default is `2`. If the value is less than `0` the value is set to `0`, and if the value is more that `15` the value is set to `15`,
|
|
@@ -52,32 +59,54 @@ Promise.config({ cancellation: true });
|
|
|
52
59
|
* return (statusCode && (Math.floor(statusCode / 100) === 5 || statusCode === 429)) || (!statusCode && !args[1].message.includes('Invalid URI'));
|
|
53
60
|
* };
|
|
54
61
|
*```
|
|
62
|
+
* If logLevel is empty, request and response will be logged as info and the response will be in response property with full details. Error on the request will generate a warning. If logLevel is not empty but not complete, logLevel will take control over default.
|
|
55
63
|
*
|
|
64
|
+
* If not alredy set,the user agent will the set to `mimik-{serverType}/{serverVersion}/{serverId} {architecture} {node}`;
|
|
65
|
+
*
|
|
66
|
+
* To facilitate the transition from request-promise the following action are taken on options:
|
|
67
|
+
* - `uri` takes precednce on `url`
|
|
68
|
+
* - `body` takes precedence on `json` if `json` is an object and are used to assign `data`
|
|
69
|
+
* - `qs` is used to assign to `params`
|
|
56
70
|
*/
|
|
57
|
-
const rpRetry = (
|
|
58
|
-
const
|
|
71
|
+
const rpRetry = (origOptions) => {
|
|
72
|
+
const { CancelToken } = axios;
|
|
73
|
+
const source = CancelToken.source();
|
|
74
|
+
const options = origOptions;
|
|
75
|
+
const correlationId = (options.headers && options.headers['x-correlation-id']) ? options.headers['x-correlation-id'] : getCorrelationId();
|
|
59
76
|
const errors = [];
|
|
60
77
|
const delayPromises = [];
|
|
78
|
+
const criteria = validateOptions(options, correlationId);
|
|
79
|
+
const { logLevel } = criteria;
|
|
80
|
+
const logLevelLength = Object.keys(logLevel).length;
|
|
61
81
|
let nbRetries = 0;
|
|
82
|
+
let mainTimeout;
|
|
62
83
|
|
|
63
|
-
|
|
84
|
+
if (!options.headers) options.headers = { 'user-agent': getUserAgent() };
|
|
85
|
+
else if (!options.headers['user-agent']) options.headers['user-agent'] = getUserAgent();
|
|
86
|
+
options.cancelToken = source.token;
|
|
87
|
+
|
|
88
|
+
const retryProcess = (nbRetry) => rp(options)
|
|
64
89
|
.then((response) => {
|
|
65
|
-
const info = { options
|
|
90
|
+
const info = { options, nbRetries, errors };
|
|
66
91
|
|
|
67
|
-
if (
|
|
68
|
-
info[
|
|
69
|
-
logger[
|
|
92
|
+
if (logLevel.response) {
|
|
93
|
+
info[logLevel.responseName] = setResponse(response, logLevel.responseDetails);
|
|
94
|
+
logger[logLevel.response]('request response', info, correlationId);
|
|
95
|
+
}
|
|
96
|
+
else if (logLevelLength === 0) {
|
|
97
|
+
info[DEFAULT_RESPONSE_NAME] = setResponse(response, DEFAULT_LOGLEVEL_DETAILS);
|
|
98
|
+
logger[DEFAULT_LOGLEVEL_RESPONSE]('request response', info, correlationId);
|
|
70
99
|
}
|
|
71
100
|
return response;
|
|
72
101
|
})
|
|
73
102
|
.catch((err) => {
|
|
74
|
-
if ((nbRetry <
|
|
103
|
+
if ((nbRetry < criteria.retries) && isRetry(options, nbRetry, criteria, err, correlationId)) {
|
|
75
104
|
nbRetries = nbRetry + 1;
|
|
76
|
-
errors.push(err
|
|
77
|
-
const delayPromise = Promise.delay(calculateDelay(
|
|
105
|
+
errors.push(err);
|
|
106
|
+
const delayPromise = Promise.delay(calculateDelay(options, nbRetry, criteria, err, correlationId));
|
|
78
107
|
|
|
79
108
|
delayPromises.unshift(delayPromise);
|
|
80
|
-
return delayPromise.then(() => retryProcess(
|
|
109
|
+
return delayPromise.then(() => retryProcess(nbRetry + 1));
|
|
81
110
|
}
|
|
82
111
|
const error = err;
|
|
83
112
|
|
|
@@ -88,36 +117,49 @@ const rpRetry = (options) => {
|
|
|
88
117
|
errors,
|
|
89
118
|
};
|
|
90
119
|
}
|
|
91
|
-
throw getRichError(
|
|
120
|
+
throw getRichError(
|
|
121
|
+
error.statusCode,
|
|
122
|
+
'request error response',
|
|
123
|
+
{ options },
|
|
124
|
+
error,
|
|
125
|
+
logLevel.error || ((logLevelLength === 0) ? DEFAULT_LOGLEVEL_ERROR : undefined),
|
|
126
|
+
correlationId,
|
|
127
|
+
);
|
|
92
128
|
});
|
|
93
129
|
|
|
94
|
-
|
|
95
|
-
const criteria = validateOptions(options);
|
|
96
|
-
const retryPromise = retryProcess(options, 0, criteria, correlationId);
|
|
130
|
+
const retryPromise = retryProcess(0);
|
|
97
131
|
const mainTimeoutPromise = new Promise((resolve, reject) => {
|
|
98
132
|
mainTimeout = setTimeout(() => {
|
|
99
|
-
delayPromises.forEach((delayPromise) => delayPromise.cancel());
|
|
100
|
-
|
|
133
|
+
delayPromises.forEach((delayPromise) => delayPromise.cancel(`retry timeout, ${criteria.timeout}, ${nbRetries}`));
|
|
134
|
+
source.cancel(`retry timeout, ${criteria.timeout}, ${nbRetries}`);
|
|
101
135
|
let error = new Error('retry timeout');
|
|
102
136
|
|
|
103
137
|
if (nbRetries !== 0) {
|
|
104
138
|
error.info = { retry: { nbRetries, errors } };
|
|
105
139
|
}
|
|
106
140
|
error.name = 'TimeoutError';
|
|
107
|
-
error = getRichError(
|
|
141
|
+
error = getRichError(
|
|
142
|
+
'System',
|
|
143
|
+
'request error response',
|
|
144
|
+
{ options },
|
|
145
|
+
error,
|
|
146
|
+
logLevel.error || ((logLevelLength === 0) ? DEFAULT_LOGLEVEL_ERROR : undefined),
|
|
147
|
+
correlationId,
|
|
148
|
+
);
|
|
108
149
|
reject(error);
|
|
109
150
|
}, criteria.timeout * 1000);
|
|
110
151
|
});
|
|
111
152
|
|
|
112
|
-
if (
|
|
153
|
+
if (logLevel.request) logger[logLevel.request]('making a request', { options, criteria }, correlationId);
|
|
154
|
+
else if (logLevelLength === 0) logger[DEFAULT_LOGLEVEL_REQUEST]('making a request', { options, criteria }, correlationId);
|
|
113
155
|
return Promise.race([retryPromise, mainTimeoutPromise])
|
|
114
156
|
.then((result) => {
|
|
115
|
-
mainTimeoutPromise.cancel();
|
|
157
|
+
mainTimeoutPromise.cancel('main timeout');
|
|
116
158
|
clearTimeout(mainTimeout);
|
|
117
159
|
return result;
|
|
118
160
|
})
|
|
119
161
|
.catch((err) => {
|
|
120
|
-
mainTimeoutPromise.cancel();
|
|
162
|
+
mainTimeoutPromise.cancel(`main timeout error: ${err.message}`);
|
|
121
163
|
clearTimeout(mainTimeout);
|
|
122
164
|
throw err;
|
|
123
165
|
});
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const axios = require('axios');
|
|
2
|
+
const _ = require('lodash');
|
|
3
|
+
|
|
4
|
+
const { getRichError } = require('@mimik/response-helper');
|
|
5
|
+
|
|
6
|
+
const rp = (origOptions) => {
|
|
7
|
+
const options = _.clone(origOptions);
|
|
8
|
+
|
|
9
|
+
if (options.uri) options.url = options.uri;
|
|
10
|
+
delete options.uri;
|
|
11
|
+
delete options.validateStatus;
|
|
12
|
+
if (options.body) {
|
|
13
|
+
options.data = options.body;
|
|
14
|
+
delete options.body;
|
|
15
|
+
}
|
|
16
|
+
else if (typeof options.json === 'object') {
|
|
17
|
+
options.data = options.body;
|
|
18
|
+
delete options.json;
|
|
19
|
+
}
|
|
20
|
+
else delete options.json;
|
|
21
|
+
if (options.qs) options.params = options.qs;
|
|
22
|
+
return axios(options)
|
|
23
|
+
.then((res) => {
|
|
24
|
+
if (options.resolveWithFullResponse) return res;
|
|
25
|
+
return res.data;
|
|
26
|
+
})
|
|
27
|
+
.catch((err) => {
|
|
28
|
+
const { response } = err;
|
|
29
|
+
let errorMsg = 'no response';
|
|
30
|
+
|
|
31
|
+
if (err.message) errorMsg = `${errorMsg}: ${err.message}`;
|
|
32
|
+
if (!response) {
|
|
33
|
+
throw getRichError('System', errorMsg, {
|
|
34
|
+
code: err.code,
|
|
35
|
+
address: err.address,
|
|
36
|
+
port: err.port,
|
|
37
|
+
syscall: err.syscall,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
const { data } = response;
|
|
41
|
+
|
|
42
|
+
throw getRichError(response.status, data ? data.message || response.statusText : response.statusText, data);
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
module.exports = {
|
|
47
|
+
rp,
|
|
48
|
+
};
|
package/lib/validate.js
CHANGED
|
@@ -3,7 +3,7 @@ const logger = require('@mimik/sumologic-winston-logger');
|
|
|
3
3
|
const DETAILS = ['full', 'type', 'count'];
|
|
4
4
|
const TYPE = DETAILS[1];
|
|
5
5
|
const RESPONSE = 'response';
|
|
6
|
-
const
|
|
6
|
+
const DEFAULT_LOGLEVEL = logger.LEVELS[5]; // silly
|
|
7
7
|
const DEFAULT_RETRIES = 2;
|
|
8
8
|
const MIN_RETRIES = 0;
|
|
9
9
|
const MAX_RETRIES = 15;
|
|
@@ -22,7 +22,7 @@ const defaultRetry = (...args) => {
|
|
|
22
22
|
const unknownRetry = () => true;
|
|
23
23
|
const defaultDelay = () => DEFAULT_DELAY;
|
|
24
24
|
|
|
25
|
-
const validateOptions = (options) => {
|
|
25
|
+
const validateOptions = (options, correlationId) => {
|
|
26
26
|
if (!options.retry) {
|
|
27
27
|
return {
|
|
28
28
|
delay: DEFAULT_DELAY,
|
|
@@ -44,22 +44,22 @@ const validateOptions = (options) => {
|
|
|
44
44
|
const validateLogLevel = (val, name) => {
|
|
45
45
|
if (!val[name]) return null;
|
|
46
46
|
if (!logger.LEVELS.includes(val[name])) {
|
|
47
|
-
logger.warn(`invalid logLevel.${name}, reset to default`, { name, value: val[name], default:
|
|
48
|
-
return
|
|
47
|
+
logger.warn(`invalid logLevel.${name}, reset to default`, { name, value: val[name], default: DEFAULT_LOGLEVEL }, correlationId);
|
|
48
|
+
return DEFAULT_LOGLEVEL;
|
|
49
49
|
}
|
|
50
50
|
return val[name];
|
|
51
51
|
};
|
|
52
52
|
const validateValue = (val, name, defaultValue, minValue, maxValue) => {
|
|
53
53
|
if (typeof val !== 'number') {
|
|
54
|
-
if (val) logger.warn(`invalid ${name}, reset to default`, { type: typeof val, defaultValue });
|
|
54
|
+
if (val) logger.warn(`invalid ${name}, reset to default`, { type: typeof val, defaultValue }, correlationId);
|
|
55
55
|
return defaultValue;
|
|
56
56
|
}
|
|
57
57
|
if (val < minValue) {
|
|
58
|
-
logger.warn(`out of scope ${name}, reset to min`, { value: val, minValue });
|
|
58
|
+
logger.warn(`out of scope ${name}, reset to min`, { value: val, minValue }, correlationId);
|
|
59
59
|
return minValue;
|
|
60
60
|
}
|
|
61
61
|
if (val > maxValue) {
|
|
62
|
-
logger.warn(`out of scope ${name}, reset to max`, { value: val, maxValue });
|
|
62
|
+
logger.warn(`out of scope ${name}, reset to max`, { value: val, maxValue }, correlationId);
|
|
63
63
|
return maxValue;
|
|
64
64
|
}
|
|
65
65
|
return val;
|
|
@@ -67,7 +67,7 @@ const validateOptions = (options) => {
|
|
|
67
67
|
const validateResponseDetails = (val, name, defaultValue) => {
|
|
68
68
|
if (!val) return defaultValue;
|
|
69
69
|
if (!DETAILS.includes(val)) {
|
|
70
|
-
logger.warn(`invalid logLevel.${name}, reset to default`, { name, value: val, defaultValue });
|
|
70
|
+
logger.warn(`invalid logLevel.${name}, reset to default`, { name, value: val, defaultValue }, correlationId);
|
|
71
71
|
return defaultValue;
|
|
72
72
|
}
|
|
73
73
|
return val;
|
|
@@ -75,7 +75,7 @@ const validateOptions = (options) => {
|
|
|
75
75
|
const validateResponseName = (val, name, defaultValue) => {
|
|
76
76
|
if (!val && val !== '') return defaultValue;
|
|
77
77
|
if (typeof val !== 'string' || val.length === 0 || val.trim().length === 0) {
|
|
78
|
-
logger.warn(`invalid logLevel.${name}, reset to default`, { name, value: val, defaultValue });
|
|
78
|
+
logger.warn(`invalid logLevel.${name}, reset to default`, { name, value: val, defaultValue }, correlationId);
|
|
79
79
|
return defaultValue;
|
|
80
80
|
}
|
|
81
81
|
return val;
|
|
@@ -88,14 +88,14 @@ const validateOptions = (options) => {
|
|
|
88
88
|
if (typeof delayStrategy !== 'function') {
|
|
89
89
|
if (!delayStrategy) delayStrategy = defaultDelay;
|
|
90
90
|
else {
|
|
91
|
-
logger.warn('invalid delayStrategy, using delay', { strategyType: typeof delayStrategy, delay, default: DEFAULT_DELAY });
|
|
91
|
+
logger.warn('invalid delayStrategy, using delay', { strategyType: typeof delayStrategy, delay, default: DEFAULT_DELAY }, correlationId);
|
|
92
92
|
delayStrategy = setDelay;
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
if (typeof retryStrategy !== 'function') {
|
|
96
96
|
if (!retryStrategy) retryStrategy = defaultRetry;
|
|
97
97
|
else {
|
|
98
|
-
logger.warn('invalid retryStrategy, ignoring', { strategyType: typeof retryStrategy, using: unknownRetry });
|
|
98
|
+
logger.warn('invalid retryStrategy, ignoring', { strategyType: typeof retryStrategy, using: unknownRetry }, correlationId);
|
|
99
99
|
retryStrategy = unknownRetry;
|
|
100
100
|
}
|
|
101
101
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
const express = require('express');
|
|
3
|
+
const bodyParser = require('body-parser');
|
|
4
|
+
|
|
5
|
+
const app = express();
|
|
6
|
+
|
|
7
|
+
app.use(bodyParser.json());
|
|
8
|
+
app.get('/success', (req, res) => {
|
|
9
|
+
res.statusCode = 200;
|
|
10
|
+
|
|
11
|
+
res.send({ statusCode: 200 });
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
app.listen(9000, () => {
|
|
15
|
+
console.log('----->', `retry mock at ${9000}`);
|
|
16
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
require('../test/testEnv');
|
|
3
|
+
|
|
4
|
+
const { rpRetry } = require('../index');
|
|
5
|
+
|
|
6
|
+
const correlationId = `--request-retry-test--/${new Date().toISOString()}`;
|
|
7
|
+
|
|
8
|
+
const options = {
|
|
9
|
+
method: 'GET',
|
|
10
|
+
headers: {
|
|
11
|
+
'x-correlation-id': correlationId,
|
|
12
|
+
},
|
|
13
|
+
url: 'http://localhost:9080/test/retry',
|
|
14
|
+
json: true,
|
|
15
|
+
retry: {},
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
options.retry.delayStrategy = () => 10000;
|
|
19
|
+
options.retry.timeout = 10;
|
|
20
|
+
options.retry.retries = 2;
|
|
21
|
+
|
|
22
|
+
rpRetry(options)
|
|
23
|
+
.catch((err) => console.log(err));
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
const express = require('express');
|
|
3
|
+
const bodyParser = require('body-parser');
|
|
4
|
+
|
|
5
|
+
const app = express();
|
|
6
|
+
const config = {
|
|
7
|
+
port: 9080,
|
|
8
|
+
path: '/retry',
|
|
9
|
+
base: '/test',
|
|
10
|
+
get: {
|
|
11
|
+
nbRetry: 400,
|
|
12
|
+
success: 200,
|
|
13
|
+
error: 500,
|
|
14
|
+
},
|
|
15
|
+
post: {
|
|
16
|
+
success: 201,
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
let nbRequest = 0;
|
|
20
|
+
let time = 0;
|
|
21
|
+
let message;
|
|
22
|
+
|
|
23
|
+
app.use(bodyParser.json());
|
|
24
|
+
app.get(`${config.base}${config.path}`, (req, res) => {
|
|
25
|
+
if (nbRequest === 0) message = 'Recieved first request';
|
|
26
|
+
else {
|
|
27
|
+
const timeLap = Date.now() - time;
|
|
28
|
+
|
|
29
|
+
message = `Received ${nbRequest} retry with timelap ${timeLap}`;
|
|
30
|
+
}
|
|
31
|
+
console.log('----->', message);
|
|
32
|
+
time = Date.now();
|
|
33
|
+
|
|
34
|
+
if (nbRequest === config.get.nbRetry) {
|
|
35
|
+
res.statusCode = config.get.success;
|
|
36
|
+
res.send({ statusCode: config.get.success });
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
nbRequest += 1;
|
|
40
|
+
res.statusCode = config.get.error;
|
|
41
|
+
|
|
42
|
+
res.send({ statusCode: config.get.error });
|
|
43
|
+
});
|
|
44
|
+
app.post(`${config.base}${config.path}`, (req, res) => {
|
|
45
|
+
console.log('----->', 'Received a POST request');
|
|
46
|
+
res.statusCode = config.post.success;
|
|
47
|
+
res.send({ statusCode: config.post.success });
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
app.post('/logs/:id', (req, res) => {
|
|
51
|
+
console.log('--->', 'Recieved a log');
|
|
52
|
+
console.log('---> id:', req.params.id);
|
|
53
|
+
console.log('---> body:', req.body);
|
|
54
|
+
res.statusCode = config.post.success;
|
|
55
|
+
res.send({ statusCode: config.post.success });
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
app.listen(config.port, () => {
|
|
59
|
+
console.log('----->', `retry mock at ${config.port}`);
|
|
60
|
+
});
|
package/manual-test/testRace.js
CHANGED
|
@@ -1,27 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
const doSomething = () => {
|
|
3
|
+
let add = 0;
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
for (let i = 0; i < 100000000; i += 1) {
|
|
6
|
+
add += 1;
|
|
7
|
+
console.log(add);
|
|
8
|
+
}
|
|
9
|
+
return add;
|
|
9
10
|
};
|
|
10
11
|
const timeout = 1; // ms
|
|
11
12
|
|
|
12
13
|
const race = () => {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
let result;
|
|
15
|
+
const mainTimeout = setTimeout(() => {
|
|
16
|
+
throw new Error('timeout');
|
|
17
|
+
}, timeout);
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
19
|
+
try { result = doSomething(); }
|
|
20
|
+
catch (err) {
|
|
21
|
+
console.log(err);
|
|
22
|
+
result = 0;
|
|
23
|
+
}
|
|
24
|
+
clearTimeout(mainTimeout);
|
|
25
|
+
return result;
|
|
26
|
+
};
|
|
26
27
|
|
|
27
28
|
console.log(race());
|
package/manual-test/testRetry.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
const { rpRetry } = require('../index');
|
|
2
3
|
|
|
3
4
|
const options = {
|
|
4
5
|
method: 'GET',
|
|
@@ -9,49 +10,50 @@ const options = {
|
|
|
9
10
|
json: true,
|
|
10
11
|
timeout: 200,
|
|
11
12
|
// retry: {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
//}
|
|
13
|
+
// all default: maxRetry: 2, retryDelay: 1000ms, maxTimeout: 50s, logLevel: 3 silly, type response, retryDelayStrategy: setDelay, retryStrategy: defaultRetry
|
|
14
|
+
// retries: -1, // => 0
|
|
15
|
+
// retries: 20, // => 15
|
|
16
|
+
// retries: 'joe', // => 2
|
|
17
|
+
// retries: 0, // OK
|
|
18
|
+
// delay: 0, // => 20ms
|
|
19
|
+
// delay: 100000, // => 30000ms
|
|
20
|
+
// delay: 'joe', // => 1000ms
|
|
21
|
+
// delay: 1, // => 20ms
|
|
22
|
+
// delayStrategy: 'joe', // => setDelay returning retryDelay
|
|
23
|
+
// delayStrategy: function badDelay() { return 'joe' }, // => no change then bad delay strategy => retryDelay
|
|
24
|
+
// delayStrategy: function userDelay(...args) { return (Math.pow(2, args[0]) * 100) + Math.floor(Math.random() * 50) }, // OK
|
|
25
|
+
// retryStrategy: 'joe', // => unknowRetry returning false
|
|
26
|
+
// retryStrategy: function badRetry() { return 'joe' }, // => no change then bad retry strategy => false
|
|
27
|
+
// retryStrategy: function userRetry(...args) { // OK
|
|
28
|
+
// const { statusCode } = args[1]; // err
|
|
29
|
+
//
|
|
30
|
+
// return statusCode && (Math.floor(statusCode/100) !== 5 || statusCode !== 429); // retry if there is no statusCode or if there is 500 range statucCode or 429
|
|
31
|
+
// },
|
|
32
|
+
// retryStrategy: function invalidRetry(...args) { // defaultRetry
|
|
33
|
+
// const { statusCode } = args[34]; // null value
|
|
34
|
+
//
|
|
35
|
+
// return true // no retry
|
|
36
|
+
// },
|
|
37
|
+
// timeout: 0, // => 10s
|
|
38
|
+
// timeout: 150, // => 120s
|
|
39
|
+
// timeout: 'joe', // => 50s
|
|
40
|
+
// logLevel: {
|
|
41
|
+
// response: 'test', // silly with warning
|
|
42
|
+
// error: 1234, // => silly with warning
|
|
43
|
+
// request: null, // => silly no warning
|
|
44
|
+
// responseDetails: 'test', // => type with warning
|
|
45
|
+
// responseName: '', // => response with warning
|
|
46
|
+
// },
|
|
47
|
+
// logLevel: {
|
|
48
|
+
// response: 'info', // ok all the other value to default no warning
|
|
49
|
+
// },
|
|
50
|
+
// }
|
|
50
51
|
};
|
|
51
52
|
|
|
52
53
|
const sDate = Date.now();
|
|
53
54
|
|
|
54
55
|
rpRetry(options)
|
|
55
|
-
.then(response => console.log('success', { response: typeof response }, Date.now() - sDate))
|
|
56
|
-
.catch(err => {
|
|
57
|
-
|
|
56
|
+
.then((response) => console.log('success', { response: typeof response }, Date.now() - sDate))
|
|
57
|
+
.catch((err) => {
|
|
58
|
+
console.log('failure', { error: err, info: err.info }, Date.now() - sDate);
|
|
59
|
+
});
|
package/package.json
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mimik/request-retry",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Request retry wrapping
|
|
3
|
+
"version": "2.0.8",
|
|
4
|
+
"description": "Request retry wrapping axios",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"lint": "
|
|
8
|
-
"docs": "
|
|
9
|
-
"test": "
|
|
10
|
-
"
|
|
7
|
+
"lint": "eslint --ignore-path .gitignore .",
|
|
8
|
+
"docs": "jsdoc2md index.js > README.md",
|
|
9
|
+
"test": "mocha --reporter mochawesome --bail --check-leaks test/",
|
|
10
|
+
"test-ci": "nyc --reporter=lcov --reporter=text npm test",
|
|
11
|
+
"prepublishOnly": "npm run docs && npm run lint && npm run test-ci",
|
|
12
|
+
"commit-ready": "npm run docs && npm run lint && npm run test-ci",
|
|
13
|
+
"prepare": "husky install"
|
|
11
14
|
},
|
|
12
15
|
"husky": {
|
|
13
16
|
"hooks": {
|
|
@@ -19,41 +22,39 @@
|
|
|
19
22
|
"mimik",
|
|
20
23
|
"microservice"
|
|
21
24
|
],
|
|
22
|
-
"author": "mimik",
|
|
23
|
-
"license": "
|
|
25
|
+
"author": "mimik technology inc <support@mimik.com> (https://developer.mimik.com/)",
|
|
26
|
+
"license": "MIT",
|
|
24
27
|
"repository": {
|
|
25
28
|
"type": "git",
|
|
26
29
|
"url": "https://bitbucket.org/mimiktech/request-retry"
|
|
27
30
|
},
|
|
28
31
|
"dependencies": {
|
|
29
|
-
"@mimik/
|
|
30
|
-
"@mimik/
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
32
|
+
"@mimik/request-helper": "^1.7.5",
|
|
33
|
+
"@mimik/response-helper": "^2.6.1",
|
|
34
|
+
"@mimik/sumologic-winston-logger": "^1.6.8",
|
|
35
|
+
"axios": "0.27.2",
|
|
36
|
+
"bluebird": "3.7.2",
|
|
37
|
+
"lodash": "4.17.21"
|
|
34
38
|
},
|
|
35
39
|
"devDependencies": {
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"eslint
|
|
42
|
-
"eslint-
|
|
43
|
-
"eslint-plugin-
|
|
44
|
-
"eslint-plugin-
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"nyc": "14.1.1",
|
|
56
|
-
"sinon": "7.5.0",
|
|
57
|
-
"verror": "1.10.0"
|
|
40
|
+
"@mimik/eslint-plugin-dependencies": "^2.4.3",
|
|
41
|
+
"@mimik/eslint-plugin-document-env": "^1.0.3",
|
|
42
|
+
"acorn": "8.7.1",
|
|
43
|
+
"body-parser": "1.20.0",
|
|
44
|
+
"chai": "4.3.6",
|
|
45
|
+
"eslint": "8.15.0",
|
|
46
|
+
"eslint-config-airbnb": "19.0.4",
|
|
47
|
+
"eslint-plugin-import": "2.26.0",
|
|
48
|
+
"eslint-plugin-jsx-a11y": "6.5.1",
|
|
49
|
+
"eslint-plugin-react": "7.29.4",
|
|
50
|
+
"eslint-plugin-react-hooks": "4.5.0",
|
|
51
|
+
"express": "4.18.1",
|
|
52
|
+
"husky": "8.0.1",
|
|
53
|
+
"jsdoc-to-markdown": "7.1.1",
|
|
54
|
+
"mocha": "10.0.0",
|
|
55
|
+
"mochawesome": "7.1.3",
|
|
56
|
+
"nyc": "15.1.0",
|
|
57
|
+
"sinon": "14.0.0",
|
|
58
|
+
"verror": "1.10.1"
|
|
58
59
|
}
|
|
59
60
|
}
|
package/test/retryMock.js
CHANGED
|
@@ -46,6 +46,14 @@ app.post(`${config.base}${config.path}`, (req, res) => {
|
|
|
46
46
|
res.statusCode = config.post.success;
|
|
47
47
|
res.send({ statusCode: config.post.success });
|
|
48
48
|
});
|
|
49
|
+
app.get('/stop', (req, res) => {
|
|
50
|
+
console.log('----->', 'Received a stop');
|
|
51
|
+
res.statusCode = config.get.success;
|
|
52
|
+
res.send({ statusCode: config.get.success });
|
|
53
|
+
setTimeout(() => {
|
|
54
|
+
process.exit(0);
|
|
55
|
+
}, 3000);
|
|
56
|
+
});
|
|
49
57
|
|
|
50
58
|
const listen = () => {
|
|
51
59
|
app.listen(config.port, () => {
|
package/test/rpRetry.spec.js
CHANGED
|
@@ -2,10 +2,11 @@ const chai = require('chai');
|
|
|
2
2
|
const sinon = require('sinon');
|
|
3
3
|
const VError = require('verror');
|
|
4
4
|
const { beforeEach, afterEach } = require('mocha');
|
|
5
|
+
require('./testEnv');
|
|
5
6
|
|
|
6
7
|
const logger = require('@mimik/sumologic-winston-logger');
|
|
8
|
+
const { getCorrelationId } = require('@mimik/request-helper');
|
|
7
9
|
|
|
8
|
-
require('./testEnv');
|
|
9
10
|
const mockServer = require('./retryMock');
|
|
10
11
|
const { rpRetry } = require('../index');
|
|
11
12
|
|
|
@@ -16,7 +17,7 @@ chai.should();
|
|
|
16
17
|
// const NO_ERROR = 'not an error object';
|
|
17
18
|
|
|
18
19
|
describe('request-retry Unit Tests', () => {
|
|
19
|
-
const correlationId = '--request-retry-test--';
|
|
20
|
+
const correlationId = getCorrelationId('--request-retry-test--');
|
|
20
21
|
// let loggerSpyError;
|
|
21
22
|
let loggerSpyWarn;
|
|
22
23
|
let loggerSpyInfo;
|
|
@@ -261,7 +262,7 @@ describe('request-retry Unit Tests', () => {
|
|
|
261
262
|
options.retry.retries = 2;
|
|
262
263
|
return rpRetry(options)
|
|
263
264
|
.catch(() => {
|
|
264
|
-
sinon.assert.
|
|
265
|
+
sinon.assert.called(loggerSpyWarn);
|
|
265
266
|
const callArgs = loggerSpyWarn.getCall(0).args;
|
|
266
267
|
expect(callArgs[0]).to.be.a('string');
|
|
267
268
|
expect(callArgs[0]).to.equal('bad retry strategy');
|
|
@@ -272,7 +273,7 @@ describe('request-retry Unit Tests', () => {
|
|
|
272
273
|
options.retry.retries = 2;
|
|
273
274
|
return rpRetry(options)
|
|
274
275
|
.catch(() => {
|
|
275
|
-
sinon.assert.
|
|
276
|
+
sinon.assert.called(loggerSpyWarn);
|
|
276
277
|
const callArgs = loggerSpyWarn.getCall(0).args;
|
|
277
278
|
expect(callArgs[0]).to.be.a('string');
|
|
278
279
|
expect(callArgs[0]).to.equal('bad retry strategy');
|
|
@@ -282,10 +283,8 @@ describe('request-retry Unit Tests', () => {
|
|
|
282
283
|
options.retry.retryStrategy = () => false;
|
|
283
284
|
options.retry.retries = 2;
|
|
284
285
|
return rpRetry(options)
|
|
285
|
-
.then(() => {
|
|
286
|
-
})
|
|
287
286
|
.catch(() => {
|
|
288
|
-
sinon.assert.
|
|
287
|
+
sinon.assert.called(loggerSpyWarn);
|
|
289
288
|
});
|
|
290
289
|
});
|
|
291
290
|
it('should generate warning: bad delay strategy (throwing an error), ignoring and using default delay', () => {
|
|
@@ -293,7 +292,7 @@ describe('request-retry Unit Tests', () => {
|
|
|
293
292
|
options.retry.retries = 2;
|
|
294
293
|
return rpRetry(options)
|
|
295
294
|
.catch(() => {
|
|
296
|
-
sinon.assert.
|
|
295
|
+
sinon.assert.called(loggerSpyWarn);
|
|
297
296
|
const callArgs = loggerSpyWarn.getCall(0).args;
|
|
298
297
|
expect(callArgs[0]).to.be.a('string');
|
|
299
298
|
expect(callArgs[0]).to.equal('bad delay strategy');
|
|
@@ -304,7 +303,7 @@ describe('request-retry Unit Tests', () => {
|
|
|
304
303
|
options.retry.retries = 2;
|
|
305
304
|
return rpRetry(options)
|
|
306
305
|
.catch(() => {
|
|
307
|
-
sinon.assert.
|
|
306
|
+
sinon.assert.called(loggerSpyWarn);
|
|
308
307
|
const callArgs = loggerSpyWarn.getCall(0).args;
|
|
309
308
|
expect(callArgs[0]).to.be.a('string');
|
|
310
309
|
expect(callArgs[0]).to.equal('bad delay strategy');
|
|
@@ -315,7 +314,7 @@ describe('request-retry Unit Tests', () => {
|
|
|
315
314
|
options.retry.retries = 2;
|
|
316
315
|
return rpRetry(options)
|
|
317
316
|
.catch(() => {
|
|
318
|
-
sinon.assert.
|
|
317
|
+
sinon.assert.called(loggerSpyWarn);
|
|
319
318
|
const callArgs = loggerSpyWarn.getCall(0).args;
|
|
320
319
|
expect(callArgs[0]).to.be.a('string');
|
|
321
320
|
expect(callArgs[0]).to.equal('calculated delay out of scope: using delay or default');
|
|
@@ -325,10 +324,8 @@ describe('request-retry Unit Tests', () => {
|
|
|
325
324
|
options.retry.delayStrategy = () => 50;
|
|
326
325
|
options.retry.retries = 2;
|
|
327
326
|
return rpRetry(options)
|
|
328
|
-
.then(() => {
|
|
329
|
-
})
|
|
330
327
|
.catch(() => {
|
|
331
|
-
sinon.assert.
|
|
328
|
+
sinon.assert.called(loggerSpyWarn);
|
|
332
329
|
});
|
|
333
330
|
});
|
|
334
331
|
it('should generate a timeout error', () => {
|
|
@@ -336,13 +333,26 @@ describe('request-retry Unit Tests', () => {
|
|
|
336
333
|
options.retry.timeout = 10;
|
|
337
334
|
options.retry.retries = 2;
|
|
338
335
|
return rpRetry(options)
|
|
339
|
-
.then(() => {
|
|
340
|
-
})
|
|
341
336
|
.catch((err) => {
|
|
342
337
|
expect(err.name).to.equal('System');
|
|
343
338
|
expect(VError.cause(err).name).to.equal('TimeoutError');
|
|
344
|
-
sinon.assert.
|
|
339
|
+
// sinon.assert.called(loggerSpyWarn);
|
|
345
340
|
});
|
|
346
341
|
});
|
|
342
|
+
it('should stop mock server', () => rpRetry({
|
|
343
|
+
method: 'GET',
|
|
344
|
+
headers: {
|
|
345
|
+
'x-correlation-id': correlationId,
|
|
346
|
+
},
|
|
347
|
+
url: 'http://localhost:9070/stop',
|
|
348
|
+
retry: {
|
|
349
|
+
delayStrategy: () => 100,
|
|
350
|
+
retries: 1,
|
|
351
|
+
},
|
|
352
|
+
})
|
|
353
|
+
.catch((err) => {
|
|
354
|
+
expect(err.name).to.equal('System');
|
|
355
|
+
expect(VError.cause(err).name).to.equal('TimeoutError');
|
|
356
|
+
}));
|
|
347
357
|
});
|
|
348
358
|
});
|
package/test/testEnv.js
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
|
+
/* eslint no-process-env: "off" */
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The following environment variables are set for the test:
|
|
5
|
+
*
|
|
6
|
+
* | Env variable name | Description | Default | Comments |
|
|
7
|
+
* | ----------------- | ----------- | ------- | -------- |
|
|
8
|
+
* | SUMO_LOGIC_ENDPOINT | endpoint to use to log on sumologic | null
|
|
9
|
+
* | SUMO_LOGIC_COLLECTOR_CODE | code to use to log on sumologic | null
|
|
10
|
+
* | NO_STACK | flag to have a stack associated with the log | yes
|
|
11
|
+
* | LOG_LEVEL | log level to log | error
|
|
12
|
+
* | CONSOLE_LEVEL | log level to diplay | debug
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
// process.env.SUMO_LOGIC_ENDPOINT = 'http://localhost:9080/logs/';
|
|
16
|
+
// process.env.SUMO_LOGIC_COLLECTOR_CODE = '1234';
|
|
1
17
|
process.env.SUMO_LOGIC_ENDPOINT = null;
|
|
2
18
|
process.env.SUMO_LOGIC_COLLECTOR_CODE = null;
|
|
3
19
|
process.env.NO_STACK = 'yes';
|
|
4
|
-
process.env.LOG_LEVEL = '
|
|
5
|
-
|
|
20
|
+
process.env.LOG_LEVEL = 'debug';
|
|
21
|
+
process.env.CONSOLE_LEVEL = 'debug';
|
package/Gulpfile.js
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
/* eslint-disable import/no-extraneous-dependencies */
|
|
2
|
-
const fs = require('fs');
|
|
3
|
-
const log = require('fancy-log');
|
|
4
|
-
const gulp = require('gulp');
|
|
5
|
-
const eslint = require('gulp-eslint');
|
|
6
|
-
const git = require('gulp-git');
|
|
7
|
-
const jsdoc2md = require('jsdoc-to-markdown');
|
|
8
|
-
const mocha = require('gulp-spawn-mocha');
|
|
9
|
-
|
|
10
|
-
const files = [
|
|
11
|
-
'index.js',
|
|
12
|
-
'Gulpfile.js',
|
|
13
|
-
'test/**.js',
|
|
14
|
-
'lib/**.js',
|
|
15
|
-
];
|
|
16
|
-
|
|
17
|
-
const createDocs = (done) => {
|
|
18
|
-
jsdoc2md.render({ files: 'index.js' })
|
|
19
|
-
.then((output) => fs.writeFileSync('README.md', output))
|
|
20
|
-
.catch((err) => log.error('docs creation failed:', err.message));
|
|
21
|
-
return done();
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
const lint = () => gulp.src(files)
|
|
25
|
-
.pipe(eslint({}))
|
|
26
|
-
.pipe(eslint.format())
|
|
27
|
-
.pipe(eslint.failOnError());
|
|
28
|
-
|
|
29
|
-
const add = () => gulp.src('README.md')
|
|
30
|
-
.pipe(git.add({ quiet: true }));
|
|
31
|
-
|
|
32
|
-
const test = () => gulp.src(['test/*.spec.js'])
|
|
33
|
-
.pipe(mocha({
|
|
34
|
-
reporter: 'mochawesome',
|
|
35
|
-
exit: true,
|
|
36
|
-
}));
|
|
37
|
-
|
|
38
|
-
const docs = gulp.series(createDocs, add);
|
|
39
|
-
|
|
40
|
-
gulp.task('lint', lint);
|
|
41
|
-
gulp.task('docs', docs);
|
|
42
|
-
gulp.task('test', test);
|
package/package.json.bak
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@mimik/request-retry",
|
|
3
|
-
"version": "1.0.1",
|
|
4
|
-
"description": "Request retry wrapping request-promise",
|
|
5
|
-
"main": "index.js",
|
|
6
|
-
"scripts": {
|
|
7
|
-
"lint": "gulp lint",
|
|
8
|
-
"docs": "gulp docs",
|
|
9
|
-
"test": "nyc gulp test",
|
|
10
|
-
"prepublishOnly": "gulp docs; gulp lint; npm run test",
|
|
11
|
-
"commit-ready": "gulp docs; gulp lint; npm run test"
|
|
12
|
-
},
|
|
13
|
-
"husky": {
|
|
14
|
-
"hooks": {
|
|
15
|
-
"pre-commit": "npm run commit-ready",
|
|
16
|
-
"pre-push": "npm run test"
|
|
17
|
-
}
|
|
18
|
-
},
|
|
19
|
-
"keywords": [
|
|
20
|
-
"mimik",
|
|
21
|
-
"microservice"
|
|
22
|
-
],
|
|
23
|
-
"author": "mimik",
|
|
24
|
-
"license": "Apache-2.0",
|
|
25
|
-
"repository": {
|
|
26
|
-
"type": "git",
|
|
27
|
-
"url": "https://bitbucket.org/mimiktech/request-retry"
|
|
28
|
-
},
|
|
29
|
-
"dependencies": {
|
|
30
|
-
"@mimik/response-helper": "2.2.1",
|
|
31
|
-
"@mimik/sumologic-winston-logger": "1.3.0",
|
|
32
|
-
"bluebird": "3.7.1",
|
|
33
|
-
"request": "2.88.0",
|
|
34
|
-
"request-promise": "4.2.5"
|
|
35
|
-
},
|
|
36
|
-
"devDependencies": {
|
|
37
|
-
"acorn": "7.1.0",
|
|
38
|
-
"body-parser": "1.19.0",
|
|
39
|
-
"chai": "4.2.0",
|
|
40
|
-
"eslint": "6.6.0",
|
|
41
|
-
"eslint-config-airbnb": "18.0.1",
|
|
42
|
-
"eslint-plugin-import": "2.18.2",
|
|
43
|
-
"eslint-plugin-jsx-a11y": "6.2.3",
|
|
44
|
-
"eslint-plugin-react": "7.16.0",
|
|
45
|
-
"eslint-plugin-react-hooks": "2.2.0",
|
|
46
|
-
"express": "4.17.1",
|
|
47
|
-
"fancy-log": "1.3.3",
|
|
48
|
-
"gulp": "4.0.2",
|
|
49
|
-
"gulp-eslint": "6.0.0",
|
|
50
|
-
"gulp-git": "2.9.0",
|
|
51
|
-
"gulp-spawn-mocha": "6.0.0",
|
|
52
|
-
"husky": "3.0.9",
|
|
53
|
-
"jsdoc-to-markdown": "5.0.2",
|
|
54
|
-
"mocha": "6.2.2",
|
|
55
|
-
"mochawesome": "4.1.0",
|
|
56
|
-
"nyc": "14.1.1",
|
|
57
|
-
"sinon": "7.5.0",
|
|
58
|
-
"verror": "1.10.0"
|
|
59
|
-
}
|
|
60
|
-
}
|