All Projects → wsmd → Reattempt

wsmd / Reattempt

Licence: mit
🤞 Give your functions another chance

Programming Languages

javascript
184084 projects - #8 most used programming language
typescript
32286 projects

Projects that are alternatives of or similar to Reattempt

Bugsnag Php
Bugsnag error monitoring and crash reporting tool for PHP apps
Stars: ✭ 475 (-16.67%)
Mutual labels:  error-handling, errors
Traceback with variables
Adds variables to python traceback. Simple, lightweight, controllable. Debug reasons of exceptions by logging or pretty printing colorful variable contexts for each frame in a stacktrace, showing every value. Dump locals environments after errors to console, files, and loggers. Works in Jupyter and IPython. Install with pip or conda.
Stars: ✭ 509 (-10.7%)
Mutual labels:  error-handling, errors
fail
Better error handling solution specially designed for web application servers
Stars: ✭ 27 (-95.26%)
Mutual labels:  errors, error-handling
Whoops
PHP errors for cool kids
Stars: ✭ 12,646 (+2118.6%)
Mutual labels:  error-handling, errors
messaging
Conveniently issue messages, warnings, and errors
Stars: ✭ 12 (-97.89%)
Mutual labels:  errors, functions
Bugsnag Ruby
Bugsnag error monitoring & reporting software for rails, sinatra, rack and ruby
Stars: ✭ 211 (-62.98%)
Mutual labels:  error-handling, errors
rakered
The open source components from rake.red
Stars: ✭ 28 (-95.09%)
Mutual labels:  errors, error-handling
Bugsnag Node
[DEPRECATED] Please upgrade to our Universal JS notifier "@bugsnag/js" • https://github.com/bugsnag/bugsnag-js
Stars: ✭ 48 (-91.58%)
Mutual labels:  error-handling, errors
failure
An error handling package for Go.
Stars: ✭ 24 (-95.79%)
Mutual labels:  errors, error-handling
retryx
Promise-based retry workflow library.
Stars: ✭ 21 (-96.32%)
Mutual labels:  error-handling, retry
Bugsnag Cocoa
Bugsnag crash reporting for iOS, macOS and tvOS apps
Stars: ✭ 167 (-70.7%)
Mutual labels:  error-handling, errors
go-errors
Flexible, general-purpose error handling for Go.
Stars: ✭ 17 (-97.02%)
Mutual labels:  errors, error-handling
Bugsnag Go
Automatic panic monitoring for Go and Go web frameworks, like negroni, gin, and revel
Stars: ✭ 155 (-72.81%)
Mutual labels:  error-handling, errors
errors
errors with paired message and caller stack frame
Stars: ✭ 19 (-96.67%)
Mutual labels:  errors, error-handling
Elmahcore
ELMAH for Net.Standard and Net.Core
Stars: ✭ 127 (-77.72%)
Mutual labels:  error-handling, errors
bugsnag-java
Bugsnag error reporting for Java.
Stars: ✭ 51 (-91.05%)
Mutual labels:  errors, error-handling
Eris
eris provides a better way to handle, trace, and log errors in Go 🎆
Stars: ✭ 758 (+32.98%)
Mutual labels:  error-handling, errors
Bugsnag Android Ndk
DEPRECATED - this project now lives at bugsnag/bugsnag-android
Stars: ✭ 42 (-92.63%)
Mutual labels:  error-handling, errors
safe
🛡 PHP functions smarten up to throw exceptions instead of returning false or triggering errors.
Stars: ✭ 15 (-97.37%)
Mutual labels:  errors, error-handling
jsonerror
Makes Go error-handling a breeze!
Stars: ✭ 28 (-95.09%)
Mutual labels:  errors, error-handling

reattempt

Current Release CI Build Coverage Status Licence

reattempt is a modern JavaScript library for the browser and Node.js that lets you retry asynchronous functions when they fail - because some functions deserve a second chance, or a third or maybe even several dozen or so.

📖 Table of Contents

Highlights

  • 🚀 Very lightweight: ~550 bytes minified+gzipped
  • ⚡️ Modern asynchronous JavaScript support with Promises and Async/Await
  • 💪 Flexible API that covers many cases
  • 🛠 Targeted for both the browser and Node.js
  • ⛑ Type-safety with TypeScript and a built-in decorator

Getting Started

To get started, add reattempt to your project:

npm i --save-dev reattempt

Usage

Asynchronous Promise-Based Functions

When an async function (or a function that returns a Promise) is passed to Reattempt.run, the function will be called immediately. If the functions reject with an error, Reattempt.run will retry calling that function. The function will be retried until it resolves, or until the maximum retries count is reached, whichever comes first.

import Reattempt from 'reattempt';

async function doSomethingAsync() {
  // doing async operation that may throw
  return result;
}

async function main() {
  try {
    const result = await Reattempt.run({ times: 3 }, doSomethingAsync);
  } catch (error) {
    // an error is thrown if the function rejects with an error after
    // exhausting all attempts
  }
}

Node.js Error-First Callbacks

Reattempt also works with functions following the error-first callbacks pattern. When working with these functions, instead of passing an async or Promise based function, pass a function with a single argument called done. Use this argument as the error-first callback of your function.

The function will be retried until it returns a value without an error, or until the maximum retries count is reached, whichever comes first.

import fs from 'fs';
import Reattempt from 'reattempt';

async function main() {
  try {
    const data = await Reattempt.run({ times: 3 }, done => {
      fs.readFile('./path/to/file', 'utf8', done);
    });
  } catch (error) {
    // an error is thrown if the function rejects with an error after
    // exhausting all attempts
  }
}

Custom Interface Functions

Similar to working with Node.js Error-First Callbacks, the done callback can be used to reattempt any asynchronous function with custom callback interface. For example, some APIs expects an onSuccess and onError callbacks.

The properties done.resolve and done.reject can be used to hook into any custom interface and perform reattempts as needed.

function doSomething(onSuccess, onError) {
  // some async operations
}

async function main() {
  try {
    const data = await Reattempt.run({ times: 3 }, done => {
      doSomething(done.resolve, done.reject);
    });
  } catch (error) {
    // an error is thrown if the function rejects with an error after
    // exhausting all attempts
  }
}

Intercepting Attempts

There are cases when you need to intercept an attempt call. It's possible to control the reattempt flow, by providing the onError option. This option allows you to intercept each attempt and control the reattempt flow.

import Reattempt from 'reattempt';

async function doSomething() {
  // some async operations
}

function handleError(
  error /* the error object that the function rejected with */,
  done  /* resolves the function call with a custom value */,
  abort /* bail out of remaining attempts and rejects with current error */,
) {
  if (shouldAbortRemainingAttempts) {
    abort();
  } else if (shouldSkipAttemptsAndResolve) {
    done(defaultValue);
  }
}

async function main() {
  try {
    const result = await Reattempt.run(
      { times: 10, onError: handleError },
      doSomething,
    );
  } catch (error) {
    // ...
  }
}

Working with TypeScript

Reattempt As A Decorator

Reattempt also comes as a decorator that can be imported from reattempt/decorator.

import Reattempt from 'reattempt/decorator';

class Group {
  @Reattempt({ times: 3, delay: 5000 })
  private async getUserIds() {
    const user = await fakeAPI.getUsers(this.id); // could throw!
    return users.map(user => user.id);
  }

  public async doSomething() {
    try {
      const result = await this.getUserIds();
    } catch (error) {
      // Only throws after failing 3 attempts with 5 seconds in between
    }
  }
}

Type Safe Callbacks

Reattempt can infer types of async and Promise-based functions automatically.

However, when working with error-first callbacks, you can enforce type safety by passing a type argument informing Reattempt about the list of success arguments the original function could potentially provide.

Reattempt
  .run<[string, string]>({ times: 3 }, done => {
    childProcess.exec('cat *.md | wc -w', attempt);
  })
  // resolves with an array of success type-safe arguments
  .then(([stdout, stderr]) => stdout.trim())
  .catch(error => /* ... */);

API

Methods

run(options: Options, callback: Callback): Promise

Runs and reattempt the provided callback. If the callback fails, it will be reattempted until it resolves, or until the maximum retries count options.times is reached, whichever comes first.

Returns a Promise that resolves with the result of the provided function, and rejects with the same error it could reject with.

Reattempt Options

All Reattempt methods accept an options object as the first argument with the following properties:

times: number

The number of times a function can be reattempted.

If this property is not provided Reattempt will perform the provided function once without any additional reattempts on failure.

delay?: number

The duration in milliseconds between each attempt. Defaults to 0.

If this property is not provided Reattempt will perform a reattempt as soon as the function fails.

onError?(error, done, abort): void

A callback that fires on each attempt after receiving an error. It allows you to intercept an attempt and gives you access to the error object. It passes the following parameters:

  • error: any: the error that the function rejected with
  • done(value: any): void: a function that allows you to skip remaining reattempts and resolve the attempted function with the value provided.
  • abort(): void: a function allowing you to bail out of remaining attempts and rejects the attempted function immediately.

Reattempt Callback

All Reattempt methods take a function as the second argument.

This function will be reattempted on failure and can be one of three forms:

  • An async function.
Reattempt.run({ times: 2 }, async () => {
  // ...
});
  • A function that returns a Promise
Reattempt.run({ times: 2 }, () => {
  return new Promise((resolve, reject) => {
    //...
  });
});
  • A non-async, non-Promise function that wraps functions with error-first-callbacks
Reattempt.run({ times: 2 }, done => {
  fs.readFile('path/to/file', 'utf-8', done);
});

The done Callback

If you are reattempting a non-async function (or a function that does not return a Promise), pass a callback function with one argument done.

This argument controls the reattempt flow and can be used in one of two ways:

  • As an error-first callback that you can pass to any function such as most Node.js APIs
  • As a hook to custom interfaces that expects success and error callbacks by utilizing the two properties done.resolve and done.reject.

License

MIT

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].