@mimik/request-retry 1.0.0 → 2.0.7

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 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": "latest"
30
+ "version": "detect"
19
31
  }
20
32
  },
21
33
  "globals": {
@@ -0,0 +1,4 @@
1
+ #!/bin/sh
2
+ . "$(dirname "$0")/_/husky.sh"
3
+
4
+ npm run commit-ready
@@ -0,0 +1,4 @@
1
+ #!/bin/sh
2
+ . "$(dirname "$0")/_/husky.sh"
3
+
4
+ npm run test
package/README.md CHANGED
@@ -15,7 +15,15 @@ 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
+
20
+ The following environment variable are being used:
21
+
22
+ | Env variable name | Description | Default | Comments |
23
+ | ----------------- | ----------- | ------- | -------- |
24
+ | SERVER_TYPE | type of the server instance that makes the call | generic | for defining the agent
25
+ | SERVER_VERSION |version of the server instance that makes the call | 1.0 | for defining the agent
26
+ | SERVER_ID | id of the server instance that makes the call | generic | for defining the agent
19
27
 
20
28
  The following properties are added to the `options` object under the `retry` property:
21
29
  - 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 +46,19 @@ defaultRetry = (...args) => {
38
46
  return (statusCode && (Math.floor(statusCode / 100) === 5 || statusCode === 429)) || (!statusCode && !args[1].message.includes('Invalid URI'));
39
47
  };
40
48
  ```
49
+ 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.
50
+
51
+ If not alredy set,the user agent will the set to `mimik-{serverType}/{serverVersion}/{serverId} {architecture} {node}`;
52
+
53
+ To facilitate the transition from request-promise the following action are taken on options:
54
+ - `uri` takes precednce on `url`
55
+ - `body` takes precedence on `json` if `json` is an object and are used to assign `data`
56
+ - `qs` is used to assign to `params`
41
57
 
42
58
  **Requires**: <code>module:@mimik/sumologic-winston-logger</code>, <code>module:@mimik/response-helper</code>
43
- **Fulfil**: <code>object</code> - Response of the [request-promise](https://www.npmjs.com/package/request-promise) request.
59
+ **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
60
 
45
61
  | Param | Type | Description |
46
62
  | --- | --- | --- |
47
- | options | <code>object</code> | Options for the request. Similar to [request-promise](https://www.npmjs.com/package/request-promise) options. |
63
+ | 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
64
 
package/index.js CHANGED
@@ -1,15 +1,28 @@
1
- const rp = require('request-promise');
1
+ /* eslint no-process-env: "off" */
2
2
  const Promise = require('bluebird');
3
+ const axios = require('axios');
3
4
 
4
5
  const logger = require('@mimik/sumologic-winston-logger');
5
6
  const { getRichError } = require('@mimik/response-helper');
6
-
7
+ const { getCorrelationId } = require('@mimik/request-helper');
7
8
  const {
8
9
  validateOptions,
9
10
  calculateDelay,
10
11
  isRetry,
11
12
  setResponse,
12
13
  } = require('./lib/validate');
14
+ const { rp } = require('./lib/rp-axios-wrapper');
15
+
16
+ const DEFAULT_RESPONSE_NAME = 'response';
17
+ const DEFAULT_LOGLEVEL_DETAILS = 'full';
18
+ const DEFAULT_LOGLEVEL_RESPONSE = 'info';
19
+ const DEFAULT_LOGLEVEL_ERROR = 'warn';
20
+ const DEFAULT_LOGLEVEL_REQUEST = 'info';
21
+
22
+ const nodeDescription = `${process.release.name} ${process.version} ${process.release.lts}`;
23
+ const serverDescription = `mimik-${process.env.SERVER_TYPE || 'generic'}/${process.env.SERVER_VERSION || '1.0'}/${process.env.SERVER_ID || 'generic'}`;
24
+ const platformDescription = `${process.platform}; ${process.arch}`;
25
+ const userAgent = `${serverDescription} (${platformDescription}; ${nodeDescription})`;
13
26
 
14
27
  Promise.config({ cancellation: true });
15
28
 
@@ -26,10 +39,18 @@ Promise.config({ cancellation: true });
26
39
  * @requires @mimik/sumologic-winston-logger
27
40
  * @requires @mimik/response-helper
28
41
  * @category async
29
- * @param {object} options - Options for the request. Similar to [request-promise](https://www.npmjs.com/package/request-promise) options.
42
+ * @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
43
  * @return {Promise}.
31
- * @fulfil {object} - Response of the [request-promise](https://www.npmjs.com/package/request-promise) request.
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.
44
+ * @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.
45
+ * @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.
46
+ *
47
+ * The following environment variable are being used:
48
+ *
49
+ * | Env variable name | Description | Default | Comments |
50
+ * | ----------------- | ----------- | ------- | -------- |
51
+ * | SERVER_TYPE | type of the server instance that makes the call | generic | for defining the agent
52
+ * | SERVER_VERSION |version of the server instance that makes the call | 1.0 | for defining the agent
53
+ * | SERVER_ID | id of the server instance that makes the call | generic | for defining the agent
33
54
  *
34
55
  * The following properties are added to the `options` object under the `retry` property:
35
56
  * - 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 +73,54 @@ Promise.config({ cancellation: true });
52
73
  * return (statusCode && (Math.floor(statusCode / 100) === 5 || statusCode === 429)) || (!statusCode && !args[1].message.includes('Invalid URI'));
53
74
  * };
54
75
  *```
76
+ * 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
77
  *
78
+ * If not alredy set,the user agent will the set to `mimik-{serverType}/{serverVersion}/{serverId} {architecture} {node}`;
79
+ *
80
+ * To facilitate the transition from request-promise the following action are taken on options:
81
+ * - `uri` takes precednce on `url`
82
+ * - `body` takes precedence on `json` if `json` is an object and are used to assign `data`
83
+ * - `qs` is used to assign to `params`
56
84
  */
57
- const rpRetry = (options) => {
58
- const correlationId = (options.headers && options.headers['x-correlation-id']);
85
+ const rpRetry = (origOptions) => {
86
+ const { CancelToken } = axios;
87
+ const source = CancelToken.source();
88
+ const options = origOptions;
89
+ const correlationId = (options.headers && options.headers['x-correlation-id']) ? options.headers['x-correlation-id'] : getCorrelationId();
59
90
  const errors = [];
60
91
  const delayPromises = [];
92
+ const criteria = validateOptions(options, correlationId);
93
+ const { logLevel } = criteria;
94
+ const logLevelLength = Object.keys(logLevel).length;
61
95
  let nbRetries = 0;
96
+ let mainTimeout;
97
+
98
+ if (!options.headers) options.headers = { 'user-agent': userAgent };
99
+ else if (!options.headers['user-agent']) options.headers['user-agent'] = userAgent;
100
+ options.cancelToken = source.token;
62
101
 
63
- const retryProcess = (opts, nbRetry, crit, corrId) => rp(opts)
102
+ const retryProcess = (nbRetry) => rp(options)
64
103
  .then((response) => {
65
- const info = { options: opts, nbRetries, errors };
104
+ const info = { options, nbRetries, errors };
66
105
 
67
- if (crit.logLevel.response) {
68
- info[crit.logLevel.responseName] = setResponse(response, crit.logLevel.responseDetails);
69
- logger[crit.logLevel.response]('request response', info, corrId);
106
+ if (logLevel.response) {
107
+ info[logLevel.responseName] = setResponse(response, logLevel.responseDetails);
108
+ logger[logLevel.response]('request response', info, correlationId);
109
+ }
110
+ else if (logLevelLength === 0) {
111
+ info[DEFAULT_RESPONSE_NAME] = setResponse(response, DEFAULT_LOGLEVEL_DETAILS);
112
+ logger[DEFAULT_LOGLEVEL_RESPONSE]('request response', info, correlationId);
70
113
  }
71
114
  return response;
72
115
  })
73
116
  .catch((err) => {
74
- if ((nbRetry < crit.retries) && isRetry(opts, nbRetry, crit, err, corrId)) {
117
+ if ((nbRetry < criteria.retries) && isRetry(options, nbRetry, criteria, err, correlationId)) {
75
118
  nbRetries = nbRetry + 1;
76
- errors.push(err.message);
77
- const delayPromise = Promise.delay(calculateDelay(opts, nbRetry, crit, err, corrId));
119
+ errors.push(err);
120
+ const delayPromise = Promise.delay(calculateDelay(options, nbRetry, criteria, err, correlationId));
78
121
 
79
122
  delayPromises.unshift(delayPromise);
80
- return delayPromise.then(() => retryProcess(opts, nbRetry + 1, crit, corrId));
123
+ return delayPromise.then(() => retryProcess(nbRetry + 1));
81
124
  }
82
125
  const error = err;
83
126
 
@@ -88,36 +131,49 @@ const rpRetry = (options) => {
88
131
  errors,
89
132
  };
90
133
  }
91
- throw getRichError(error.statusCode, 'request error response', { options }, error, crit.logLevel.error, corrId);
134
+ throw getRichError(
135
+ error.statusCode,
136
+ 'request error response',
137
+ { options },
138
+ error,
139
+ logLevel.error || ((logLevelLength === 0) ? DEFAULT_LOGLEVEL_ERROR : undefined),
140
+ correlationId,
141
+ );
92
142
  });
93
143
 
94
- let mainTimeout;
95
- const criteria = validateOptions(options);
96
- const retryPromise = retryProcess(options, 0, criteria, correlationId);
144
+ const retryPromise = retryProcess(0);
97
145
  const mainTimeoutPromise = new Promise((resolve, reject) => {
98
146
  mainTimeout = setTimeout(() => {
99
- delayPromises.forEach((delayPromise) => delayPromise.cancel());
100
- retryPromise.cancel();
147
+ delayPromises.forEach((delayPromise) => delayPromise.cancel(`retry timeout, ${criteria.timeout}, ${nbRetries}`));
148
+ source.cancel(`retry timeout, ${criteria.timeout}, ${nbRetries}`);
101
149
  let error = new Error('retry timeout');
102
150
 
103
151
  if (nbRetries !== 0) {
104
152
  error.info = { retry: { nbRetries, errors } };
105
153
  }
106
154
  error.name = 'TimeoutError';
107
- error = getRichError('System', 'request error response', { options }, error, criteria.logLevel.error, correlationId);
155
+ error = getRichError(
156
+ 'System',
157
+ 'request error response',
158
+ { options },
159
+ error,
160
+ logLevel.error || ((logLevelLength === 0) ? DEFAULT_LOGLEVEL_ERROR : undefined),
161
+ correlationId,
162
+ );
108
163
  reject(error);
109
164
  }, criteria.timeout * 1000);
110
165
  });
111
166
 
112
- if (criteria.logLevel.request) logger[criteria.logLevel.request]('making a request', { options, criteria }, correlationId);
167
+ if (logLevel.request) logger[logLevel.request]('making a request', { options, criteria }, correlationId);
168
+ else if (logLevelLength === 0) logger[DEFAULT_LOGLEVEL_REQUEST]('making a request', { options, criteria }, correlationId);
113
169
  return Promise.race([retryPromise, mainTimeoutPromise])
114
170
  .then((result) => {
115
- mainTimeoutPromise.cancel();
171
+ mainTimeoutPromise.cancel('main timeout');
116
172
  clearTimeout(mainTimeout);
117
173
  return result;
118
174
  })
119
175
  .catch((err) => {
120
- mainTimeoutPromise.cancel();
176
+ mainTimeoutPromise.cancel(`main timeout error: ${err.message}`);
121
177
  clearTimeout(mainTimeout);
122
178
  throw err;
123
179
  });
@@ -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 DEFAULT_LOG_LEVEL = logger.LEVELS[5]; // silly
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: DEFAULT_LOG_LEVEL });
48
- return DEFAULT_LOG_LEVEL;
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
+ });
@@ -1,27 +1,28 @@
1
- const doSomething = () => {
2
- let add = 0;
1
+ /* eslint-disable no-console */
2
+ const doSomething = () => {
3
+ let add = 0;
3
4
 
4
- for (i = 0; i < 100000000; i++) {
5
- add +=1;
6
- console.log(add)
7
- };
8
- return add
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
- let result;
14
- const mainTimeout = setTimeout(() => {
15
- throw new Error('timeout')
16
- }, timeout);
14
+ let result;
15
+ const mainTimeout = setTimeout(() => {
16
+ throw new Error('timeout');
17
+ }, timeout);
17
18
 
18
- try { result = doSomething() }
19
- catch (err) {
20
- console.log(err);
21
- result = 0;
22
- }
23
- clearTimeout(mainTimeout);
24
- return result;
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());
@@ -1,4 +1,5 @@
1
- const { rpRetry } = require('../../../common/rp-retry-34/index.js');
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
- // all default: maxRetry: 2, retryDelay: 1000ms, maxTimeout: 50s, logLevel: 3 silly, type response, retryDelayStrategy: setDelay, retryStrategy: defaultRetry
13
- // retries: -1, // => 0
14
- // retries: 20, // => 15
15
- // retries: 'joe', // => 2
16
- // retries: 0, // OK
17
- // delay: 0, // => 20ms
18
- // delay: 100000, // => 30000ms
19
- // delay: 'joe', // => 1000ms
20
- // delay: 1, // => 20ms
21
- // delayStrategy: 'joe', // => setDelay returning retryDelay
22
- // delayStrategy: function badDelay() { return 'joe' }, // => no change then bad delay strategy => retryDelay
23
- // delayStrategy: function userDelay(...args) { return (Math.pow(2, args[0]) * 100) + Math.floor(Math.random() * 50) }, // OK
24
- // retryStrategy: 'joe', // => unknowRetry returning false
25
- // retryStrategy: function badRetry() { return 'joe' }, // => no change then bad retry strategy => false
26
- // retryStrategy: function userRetry(...args) { // OK
27
- // const { statusCode } = args[1]; // err
28
- //
29
- // return statusCode && (Math.floor(statusCode/100) !== 5 || statusCode !== 429); // retry if there is no statusCode or if there is 500 range statucCode or 429
30
- // },
31
- // retryStrategy: function invalidRetry(...args) { // defaultRetry
32
- // const { statusCode } = args[34]; // null value
33
- //
34
- // return true // no retry
35
- // },
36
- // timeout: 0, // => 10s
37
- // timeout: 150, // => 120s
38
- // timeout: 'joe', // => 50s
39
- // logLevel: {
40
- // response: 'test', // silly with warning
41
- // error: 1234, // => silly with warning
42
- // request: null, // => silly no warning
43
- // responseDetails: 'test', // => type with warning
44
- // responseName: '', // => response with warning
45
- // },
46
- // logLevel: {
47
- // response: 'info', // ok all the other value to default no warning
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 => { console.log('failure', { error: err, info: err.info }, Date.now() - sDate);
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
+ });