Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/vadimkorr/fn-retry
:cat: :tiger: Retry failed function call. Dependency-free, tiny and powerfull.
https://github.com/vadimkorr/fn-retry
async await javascript js promise retry
Last synced: 19 days ago
JSON representation
:cat: :tiger: Retry failed function call. Dependency-free, tiny and powerfull.
- Host: GitHub
- URL: https://github.com/vadimkorr/fn-retry
- Owner: vadimkorr
- License: mit
- Created: 2020-07-21T20:53:03.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2023-01-06T12:22:48.000Z (almost 2 years ago)
- Last Synced: 2024-10-11T12:49:43.122Z (about 1 month ago)
- Topics: async, await, javascript, js, promise, retry
- Language: JavaScript
- Homepage:
- Size: 1.49 MB
- Stars: 7
- Watchers: 0
- Forks: 0
- Open Issues: 14
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
![fn-retry](https://pbs.twimg.com/media/EduUvk-XYAAQ7ag?format=png&name=large)
Retry failed function call.
Dependency-free, tiny (~1.5 kb gzipped) and powerfull.
[![npm](https://img.shields.io/npm/v/fn-retry.svg)](https://www.npmjs.com/package/fn-retry) [![npm](https://img.shields.io/npm/dm/fn-retry.svg)](https://www.npmjs.com/package/fn-retry)
[![GitHub repo](https://img.shields.io/badge/github-repo-green.svg?style=flat)](https://github.com/vadimkorr/fn-retry) [![GitHub followers](https://img.shields.io/github/followers/vadimkorr.svg?style=social&label=Follow)](https://github.com/vadimkorr)
[![Build Status](https://travis-ci.org/vadimkorr/fn-retry.svg?branch=master)](https://travis-ci.org/vadimkorr/fn-retry)## Installation
```bash
npm install fn-retry
yarn add fn-retry
```## Usage
### ES6
```js
import { fnRetry } from 'fn-retry'// basic example
const fn = () => {
// function that should be retried in case of errors
return 'Hello'
}const result = await fnRetry(fn, {
delays: [100, 200, 300],
})
console.log(result)
```### CommonJS
```js
const { fnRetry } = require('fn-retry')// basic example
const fn = () => {
// function that should be retried in case of errors
return 'Hello'
}const result = await fnRetry(fn, {
delays: [100, 200, 300],
})
console.log(result)
```[More examples](./example)
# API
## `fnRetry`
Base strategy with custom delays. Fn will be called at least one time. In case of errors it will wait specified amount of ms (delays array) before the next call.
```js
fnRetry(fn: Function, options: Object) => Promise
```#### fn
Function that should be retried in case of errors
#### options
| Name | Type | Default | Description |
| ------------------ | ----------- | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| delays | `Array` | `[]` | Represents delays (in ms) between failed calls, e.g. `[100, 200, 300]` - in case of error fn will be called 4 times, with specified delays between calls. |
| onCallError | `Function` | `() => null` | Called on failed fn call with the object `{ error: Error, call: number, maxCalls: number }` as an argument .
It can return optional should-stop-retries value. If returnes `true`, further retries will be stopped. It can be useful, e.g., in case of auth errors. The default value of the `fn` can be returned from `onMaxCallsExceeded` as well. |
| onMaxCallsExceeded | `Function` | `() => null` | Called when max number of `fn` calls is exceeded or when retries cancelled by `true` returned from `onCallError`.
It can return optional default value. |
| waiter | `Generator` | `null` | If passed, `delays` option will be ignored. Represents generator of delay values. Can be used for making till-success calls. In this case `maxCalls` is not passed from `onCallError` callback. |### Example
```js
// Base exampleconst fn = () => {
// some function that should be retried in case of errors
return 'Hello'
}const result = await fnRetry(fn, {
delays: [100],
onCallError: ({ error, call, maxCalls }) =>
console.log(`Call ${call} of ${maxCalls}: ${error}`),
onMaxCallsExceeded: () => console.log('max calls exceeded'),
})// Example with generator, till-success strategy
const fn = () => {
// ...
}function* waiter() {
let waitMs = 100
while (true) {
yield waitMs
waitMs *= 2
}
}
await fnRetry(fn, {
waiter,
onCallError: ({ error, call }) => console.log(`Call ${call}: ${error}`),
})// Example with generator, custom delays
const fn = () => {
// ...
}// it is the same as passing delays: [ 100, 200, 400, 800, 600 ]
function* waiter() {
let waitMs = 100
for (let i = 0; i < 5; i++) {
yield waitMs
waitMs *= 2
}
}
await fnRetry(fn, {
waiter,
onMaxCallsExceeded: () => ({}),
})
```## `fnRetryWithFibonacci`
In case of errors it will wait according to Fibonacci sequence before the next call. Fn will be called at least one time, e.g.:\
with calls equal to 5: `call failed` -> `wait 1s` -> `call failed` -> `wait 1s` -> `call failed` -> `wait 2s` -> `call failed` -> `wait 3s` -> `call failed````js
fnRetryWithFibonacci(fn: Function, options: Object) => Promise
```#### fn
Function that should be retried in case of errors
#### options
| Name | Type | Default | Description |
| ------------------ | ---------- | ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| calls | `number` | `1` | Max number of calls, e.g. if `calls` is equal to 2, then flow will look like: `call failed` -> `wait 1s` -> `call succeded`. |
| onCallError | `Function` | `() => null` | Called on failed `fn` call with the object `{ error: Error, call: number, maxCalls: number }` as an argument.
It can return optional should-stop-retries value. If returnes `true`, further retries will be stopped. It can be useful, e.g., in case of auth errors. The default value of the `fn` can be returned from `onMaxCallsExceeded` as well. |
| onMaxCallsExceeded | `Function` | `() => null` | Called when max number of `fn` calls is exceeded or when retries cancelled by `true` returned from `onCallError`.
It can return optional default value. |### Example
```js
const fn = () => {
// some function that should be retried in case of errors
return 'Hello'
}const result = await fnRetryWithFibonacci(fn, {
calls: 2,
onCallError: ({ error, call, maxCalls }) =>
console.log(`Call ${call} of ${maxCalls}: ${error}`),
onMaxCallsExceeded: () => console.log('max calls exceeded'),
})
```## Higher-order functions: `fnRetriable`, `fnRetriableWithFibonacci`
You can use wrapper version of retry functions. They just wrap `fn` that needs to be retried in case of errors, and return retriable version of the `fn`. See `options` in corresponding APIs above.
This allows you to use retried version just like you use original `fn`.```js
// function that should be retried in case of errors
const getPostById = ({ id }) =>
fetch(`https://jsonplaceholder.typicode.com/posts/${id}`).then(response =>
response.json()
)// wrap getPostById to make it retriable
const getPostByIdWithRetry = fnRetriable(getPostById, {
delays: [1000],
})
// call retriable version of getPostById
const post = await getPostByIdWithRetry({ id: 1 })
console.log(post)
```# Testing
Clone the repository and execute:
```bash
yarn test
npm test
```