npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@servisbot/sb-fetch-retry

v2.1.1

Published

A module for performing fetch calls with configurable retry behavior.

Downloads

342

Readme

sb-fetch-retry

A module for performing fetch calls with configurable retry behavior.

Prerequisites

The module was originally designed to work with AWS Lambdas and uses the following environment variables if no client metadata is provided in the fetch retry options:

SERVISBOT_REGION=eu-private-4
AWS_LAMBDA_FUNCTION_NAME=some-lambda-name

SBFetchRetry

The SbFetchRetry class is the main entry point for making fetch calls with retry functionality.

To correctly instantiate a SBFetchRetry object you must provide the following to the constructor of the class:

  • The node-fetch module for making fetch calls, which can be found here: https://www.npmjs.com/package/node-fetch
  • An instance of the ServisBOT logger, which can be found here: https://github.com/servisbot/sb-logger
    • Any logger containing debug, info, warn & error functions will also work.

An example of instantiating an SBFetchRetry object with the correct parameters and environment variables can be seen below.

const Logger = require("@servisbot/sb-logger");
const fetch = require("node-fetch");
const { SBFetchRetry } = require("@servisbot/sb-fetch-retry");

const sbFetchRetry = new SBFetchRetry({ logger: new Logger(), fetch });

To perform a fetch call with configured retry behavior you may do the following:

const {
  SBFetchRetry,
  SBFetchRetryOptions,
} = require("@servisbot/sb-fetch-retry");

const sbFetchRetry = new SBFetchRetry({ logger: new Logger(), fetch });

const url = new URL('https://test.test');
const fetchOptions = {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ data: "value" }),
};
const sbFetchRetryOptions = new SBFetchRetryOptions({
  statusCodes: [429],
  maxRetries: 2,
  retryDelay: 2000,
});

// where fetchResponse is a response object from node fetch
const fetchResponse = await sbFetchRetry.fetch(
  url,
  fetchOptions,
  sbFetchRetryOptions
);

if (fetchResponse.ok) {
  const jsonBody = await fetchResponse.json();
  console.log("Ok!", jsonBody);
} else {
  const status = fetchResponse.status;
  const errorText = await fetchResponse.text();
  console.log(`Bad Response, with status ${status} with reason: ${errorText}`);
}

The above example uses the SBFetchRetryOptions class to configure the behavior of the fetch retry logic. We will discuss these options in more detail in a later section - Configuring SBFetchRetryOptions. For now you can read the example above as follows:

  • Retry the fetch call if you receive a network error or a status code of 429.
  • Retry the fetch call a maximum of 2 times.
  • Add a delay of 2000ms between each retry attempt (2 seconds).

If you do not wish to configure the retry options and would rather use the default options, you can use omit the sbRetryOptions parameter when calling the fetch function. An example can be seen below:

const {
  SBFetchRetry,
  SBFetchRetryOptions,
} = require("@servisbot/sb-fetch-retry");

const sbFetchRetry = new SBFetchRetry({ logger: new Logger(), fetch });

const url = new URL('https://test.test');
const fetchOptions = {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ data: "value" }),
};

// where fetchResponse is a response object from node fetch
const fetchResponse = await sbFetchRetry.fetch(
  url,
  fetchOptions
);

if (fetchResponse.ok) {
  const jsonBody = await fetchResponse.json();
  console.log("Ok!", jsonBody);
} else {
  const status = fetchResponse.status;
  const errorText = await fetchResponse.text();
  console.log(`Bad Response, with status ${status} with reason: ${errorText}`);
}

The above example uses the default SBFetchRetryOptions to configure the behavior of the fetch retry logic. We will discuss these default options in more detail in a later section - Default SBFetchRetryOptions. For now you can read the example above as follows:

  • Retry the fetch call a maximum of 3 times. (default value)
  • Add a delay of 1000ms between each retry attempt (1 seconds).

It is also possible to use a string as the URL:

const url = 'https://test.test';
const fetchOptions = {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ data: "value" }),
};
const sbFetchRetryOptions = new SBFetchRetryOptions({
  statusCodes: [429],
  maxRetries: 2,
  retryDelay: 2000,
});

const fetchResponse = await sbFetchRetry.fetch(
  url,
  fetchOptions
);
// as above

SBFetchRetryOptions

The SBFetchRetryOptions class can be used to configure some of the retry behavior of the SBFetchRetry class. The constructor takes in an object which represents the options to configure. The following options are available:

  • statusCodes - an array of status codes to retry on e.g. [429, 400] would cause a retry to occur if the status code from the response is 429 or 400. This is optional and defaults to an empty array. If the array is empty, then the request will not retry based on the status code.
  • maxRetries - A positive integer representing the maximum number of times to retry the request before returning the response. e.g. specifying 3 here would allow for a maximum of 3 retries to occur before the response the latest response is returned. If a request is successful before this number is reached the successful result will be returned. This is optional and defaults to 3. If the max retries is greater than 10, it will be clamped to 10.
  • retryDelay - A positive integer representing the delay in milliseconds to add between each retry attempt. This number will increase exponentially for each retry e.g. adding a retry delay of 2000 will wait 2 seconds before the first, 4 seconds before the second etc. This is optional and will default to 1000ms. If the retry delay is smaller than 250 it will be clamped to 250, and if it is greater than 5000 it will be clamped to 5000.
  • clientMetadata - An instance of the ClientMetadata class. This client metadata will be used to create logs containing client information when network errors are detected.

Default Options

To use the default options you can use the static function constructWithDefaults method on the SBFetchRetryOptions class.

const { SBFetchRetryOptions } = require("@servisbot/sb-fetch-retry");

const sbFetchRetryOptions = SBFetchRetryOptions.constructWithDefaults();

The default values are as follows:

  • statusCodes - defaults to an empty array
  • maxRetries - defaults to 3.
  • retryDelay - defaults to 1000ms.
  • clientMetadata - defaults to using lambda environment variables

Configuring Retry Options

To configure the options you can construct a new instance of the SBFetchRetryOptions and supply your own retry options. The following options are available to configure:

  • statusCodes - an array of status codes to retry on e.g. [429, 400] would cause a retry to occur if the status code from the response is 429 or 400. This is optional and defaults to an empty array.
  • maxRetries - the maximum number of times to retry the request before returning the response. e.g. specifying 3 here would allow for a maximum of 3 retries to occur before the response the latest response is returned. If a request is successful before this number is reached the successful result will be returned. This is optional and defaults to 3.
  • retryDelay - the delay in milliseconds to add between each retry attempt. e.g. adding a retry delay of 2000 will wait 2 seconds before each retry attempt. This is optional and will default to 1000ms.
  • clientMetadata - An instance of the ClientMetadata class. This client metadata will be used to create logs containing client information when network errors are detected.

An example of instantiating an SBFetchRetryOptions object can be seen below:

const { SBFetchRetryOptions, ClientMetadata } = require("@servisbot/sb-fetch-retry");

const sbFetchRetryOptions = new SBFetchRetryOptions({
  statusCodes: [429],
  maxRetries: 2,
  retryDelay: 2000,
  clientMetadata: new ClientMetadata({ 
    organization: 'acme', 
    sbRegion: 'eu-1', 
    clientType: 'browser',
    clientName: 'venus-runtime'
  })
});

The above example shows a SBFetchRetryOptions object being configured for the following:

  • Retry the request when a status code of 429 is received.
  • The maximum amount of retries is 2.
  • The delay between each request is 2000 milliseconds or 2 seconds.
  • When a network error is detected a log will be created using the client metadata provided.

Network Errors

If the module attempts to make a fetch call and it fails in an unexpected manner there will not be a status code to retry on. However the module will retry the call until the request is either successful or has reached the maximum number of retry attempts. If the maximum number of retry attempts is reached and the fetch call is still receiving unexpected errors, the error will be thrown.

Logging Network Errors

If a network error is detected a log is created with the following attributes:

Default

  • The module will attempt to use the SERVISBOT_REGION and AWS_LAMBDA_FUNCTION_NAME environment variables to generate the SRN.
{
    srn: 'srn:monitor:eu-private-4:helium:lambda:some-lambda',
    action: 'network-request',
    actionType: 'failed',
    details: { attempt: 1, url: 'some-url' }
}

Duration logs

Every network request will log it's duration, failed network requests will have a status of -1:

{ "url": "https://test.com", "duration": 222, "status": 201 }

Provided

  • If you provide your own client metadata the log will use the client metadata to build the SRN
  • For example, if you pass the following client metadata
const clientMetadata = new ClientMetadata({ 
  organization: 'acme', 
  sbRegion: 'eu-1', 
  clientType: 'browser',
  clientName: 'venus-runtime'
});

You log will look like the following:

{
    srn: 'srn:monitor:eu-private-4:acme:browser:venus-runtime',
    action: 'network-request',
    actionType: 'failed',
    details: { attempt: 1, url: 'some-url' }
}

Servisbot Logger

  • If you pass the servisbot logger in to the module it will attempt to log the network error using the following logger.app.privatePerformance.reliability
  • If the logger does not contain logger.app.privatePerformance.reliability, then logger.info is used.