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

phin-retry

Package Overview
Dependencies
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

phin-retry - npm Package Compare versions

Comparing version 1.0.0 to 1.0.1

12

package.json
{
"name": "phin-retry",
"version": "1.0.0",
"version": "1.0.1",
"description": "The ultra-lightweight Node.js HTTP client",

@@ -10,3 +10,4 @@ "main": "src/index.js",

"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "uvu tests",
"coverage": "c8 --include=src npm test && c8 report --reporter=text-lcov > coverage/lcov.info"
},

@@ -41,3 +42,8 @@ "repository": {

"node": ">=8"
},
"devDependencies": {
"c8": "^7.2.1",
"pactum": "^1.0.26",
"uvu": "^0.3.1"
}
}
}
# phin-retry
![Build](https://github.com/ASaiAnudeep/phin-retry/workflows/Build/badge.svg?branch=master)
![Coverage](https://img.shields.io/codeclimate/coverage/ASaiAnudeep/phin-retry)
The ultra-lightweight Node.js HTTP client.

@@ -19,29 +22,62 @@

// should be used in async context
const post1 = await request.get('https://jsonplaceholder.typicode.com/posts/1');
const response = await request.get('https://jsonplaceholder.typicode.com/posts/1');
const post2 = await request.get({
url: 'https://jsonplaceholder.typicode.com/posts',
qs: {
id: 1
},
await request.post({
url: 'http://localhost:9393/api/post',
body: { msg: 'input' },
retry: 3,
delay: 500
});
// custom retry, error & delay strategy
const response = await request.delete({
url: 'http://localhost:9393/api/delete',
auth: {
user: 'name',
pass: 'secret'
},
errorStrategy: (response, error, options) => {
if (error) return true;
if (response.statusCode >= 400) {
return false;
}
return true;
},
retryStrategy: (response, error, options) => {
if (error) return true;
if (options.method === 'POST') return false;
if (response.statusCode >=200 && response.StatusCode < 300) {
return false;
}
return true;
},
delayStrategy: (response, error, options, delay) => {
if (error) return 5000;
return 2000;
},
});
```
All options from **phin** are supported. Refer [Phin](https://www.npmjs.com/package/phin) for more usage examples.
* It supports **get**, **post**, **put**, **delete**, **patch** HTTP methods.
* By default, this library will retry once on failure (StatusCode >= 500 & network errors) with a delay of 100 or 1000 milliseconds. Override this behaviour with custom retry strategy function.
* Responses with status codes < 200 & >= 300 are thrown as errors. Override this behaviour with custom error strategy function.
* All options from **phin** are supported. Refer [Phin](https://www.npmjs.com/package/phin) for more usage examples.
## API
### Methods
### Defaults
| Method | Description | Usage |
| -------- | ------------------------------------------ | ---------------------------- |
| `get` | performs a GET request on the resource | `await request.get({})` |
| `post` | performs a POST request on the resource | `await request.post({})` |
| `put` | performs a PUT request on the resource | `await request.put({})` |
| `delete` | performs a DELETE request on the resource | `await request.delete({})` |
| `patch` | performs a PATCH request on the resource | `await request.patch({})` |
| `head` | performs a HEAD request on the resource | `await request.head({})` |
Access default options through `request.defaults`.
| Option | Type | Description |
| ---------------- | -------- | ---------------------------------- |
| `retry` | number | max no of times to retry (1) |
| `delay` | number | delay between retries (100ms) |
| `networkErrorDelay` | any | delay for network errors (1000ms) |
| `retryStrategy` | function | default retry strategy function |
| `delayStrategy` | function | default delay strategy function |
| `errorStrategy` | function | default error strategy function |
### Options

@@ -51,12 +87,14 @@

| Method | Type | Description |
| ---------------- | -------- | --------------------------- |
| `url` | string | request url |
| `qs` | object | query parameters |
| `auth` | object | authentication object |
| `retry` | number | max no of times to retry |
| `delay` | number | delay between retries |
| `body` | any | equivalent to data in phin |
| `fullResponse` | boolean | returns full phin response |
**By default, this library will retry once on failure (StatusCode < 200 & >= 300 ) with a delay of 100 milliseconds.**
| Method | Type | Description |
| ---------------- | -------- | ------------------------------- |
| `url` | string | request url |
| `qs` | object | query parameters |
| `auth` | object | authentication object |
| `headers` | object | headers object |
| `retry` | number | max no of times to retry |
| `delay` | number | delay between retries |
| `body` | any | equivalent to data in phin |
| `fullResponse` | boolean | returns full phin response |
| `retryStrategy` | function | custom retry strategy function |
| `delayStrategy` | function | custom delay strategy function |
| `errorStrategy` | function | custom error strategy function |

@@ -7,2 +7,5 @@ const phin = require('phin');

* @property {number} [delay] - delay in ms between retries - defaults to 100ms
* @property {function} [retryStrategy] - custom retry strategy function
* @property {function} [delayStrategy] - custom delay strategy function
* @property {function} [errorStrategy] - custom error strategy function
* @property {object} [qs] - key-value pairs of query parameters

@@ -21,12 +24,55 @@ * @property {object} [auth] - auth object

class StatusCodeError extends Error {
constructor(response) {
super(response.statusCode + `${response.statusMessage ? ` - ${response.statusMessage}` : ''}`);
constructor(response, fullResponse) {
const message = response.statusMessage ? response.statusMessag : '';
super(`${response.statusCode} - ${message}`);
this.name = this.constructor.name;
this.statusCode = response.statusCode;
this.statusMessage = response.statusMessage;
this.body = helper.json(response.body);
if (fullResponse) {
this.response = response;
}
}
}
const DEFAULT_RETRY = 1;
const DEFAULT_DELAY = 100;
const strategies = {
retry(response, error) {
if (error) {
return true;
}
if (response.statusCode >= 500) {
return true;
}
return false;
},
delay(response, error, options, delay) {
if (error && delay === defaults.delay) {
return defaults.networkErrorDelay;
}
return delay;
},
error(response, error) {
if (error) {
return true;
}
if (response.statusCode < 200 || response.statusCode >= 300) {
return true;
}
return false;
}
};
const defaults = {
retry: 1,
delay: 100,
networkErrorDelay: 1000,
retryStrategy: strategies.retry,
delayStrategy: strategies.delay,
errorStrategy: strategies.error
};
const helper = {

@@ -41,5 +87,4 @@

return buffer.toString();
} else {
return buffer;
}
return buffer;
},

@@ -57,21 +102,21 @@

retry(options) {
if (typeof options.retry === 'number') {
return options.retry;
} else if (typeof process.env.PHIN_RETRY === 'number') {
return process.env.PHIN_RETRY;
} else {
return DEFAULT_RETRY;
}
return typeof options.retry === 'number' ? options.retry : defaults.retry;
},
delay(options) {
if (typeof options.delay === 'number') {
return options.delay;
} else if (typeof process.env.PHIN_DELAY === 'number') {
return process.env.PHIN_DELAY;
} else {
return DEFAULT_DELAY;
}
return typeof options.delay === 'number' ? options.delay : defaults.delay;
},
retryStrategy(options) {
return typeof options.retryStrategy === 'function' ? options.retryStrategy : defaults.retryStrategy;
},
delayStrategy(options) {
return typeof options.delayStrategy === 'function' ? options.delayStrategy : defaults.delayStrategy;
},
errorStrategy(options) {
return typeof options.errorStrategy === 'function' ? options.errorStrategy : defaults.errorStrategy;
},
qs(options) {

@@ -113,2 +158,5 @@ if (options.qs && typeof options.qs === 'object') {

delete options.body;
delete options.retryStrategy;
delete options.delayStrategy;
delete options.errorStrategy;
},

@@ -119,2 +167,5 @@

const delay = helper.delay(options);
const retryStrategy = helper.retryStrategy(options);
const delayStrategy = helper.delayStrategy(options);
const errorStrategy = helper.errorStrategy(options);
const fullResponse = options.fullResponse || false;

@@ -125,3 +176,26 @@ helper.qs(options);

helper.delete(options);
return { retry, delay, fullResponse };
return { retry, delay, fullResponse, retryStrategy, delayStrategy, errorStrategy };
},
updateOptions(options, retry, delay, fullResponse, retryStrategy, errorStrategy) {
options.retry = retry - 1;
options.delay = delay;
options.fullResponse = fullResponse;
options.retryStrategy = retryStrategy;
options.errorStrategy = errorStrategy;
},
reject(response, error, full) {
if (error) {
throw error;
}
throw new StatusCodeError(response, full);
},
resolve(response, full) {
if (full) {
return response;
} else {
return helper.json(response.body);
}
}

@@ -133,2 +207,5 @@

defaults,
phin,
/**

@@ -139,3 +216,3 @@ * @param {RequestOptions} options

options.method = 'GET';
return this.__fetch( options);
return this.__fetch(options);
},

@@ -183,31 +260,21 @@

__fetch(opts) {
async __fetch(opts) {
const options = typeof opts === 'string' ? { url: opts, method: 'GET' } : opts;
const { retry, delay, fullResponse } = helper.init(options);
return phin(options)
.then(async res => {
if (res.statusCode < 200 || res.statusCode >= 300) {
if (retry > 0) {
options.retry = retry - 1;
options.delay = delay;
options.fullResponse = fullResponse;
await helper.sleep(delay);
return this[options.method.toLowerCase()](options);
} else {
const error = new StatusCodeError(res);
if (fullResponse) {
error.response = res;
} else {
error.body = helper.json(res.body);
}
return Promise.reject(error);
}
} else {
if (fullResponse) {
return Promise.resolve(res);
} else {
return Promise.resolve(helper.json(res.body));
}
}
});
const { retry, delay, fullResponse, retryStrategy, delayStrategy, errorStrategy } = helper.init(options);
let res, err;
try {
res = await phin(options);
} catch (error) {
err = error;
}
if (retryStrategy(res, err, options) && retry > 0) {
helper.updateOptions(options, retry, delay, fullResponse, retryStrategy, errorStrategy);
await helper.sleep(delayStrategy(res, err, options, delay));
return this[options.method.toLowerCase()](options);
}
if (errorStrategy(res, err, options)) {
return helper.reject(res, err, fullResponse);
} else {
return helper.resolve(res, fullResponse);
}
}

@@ -214,0 +281,0 @@

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