@servisbot/sb-fetch-retry

2.1.1 • Public • Published

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:

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.

Readme

Keywords

none

Package Sidebar

Install

npm i @servisbot/sb-fetch-retry

Weekly Downloads

45

Version

2.1.1

License

UNLICENSED

Unpacked Size

179 kB

Total Files

37

Last publish

Collaborators

  • servisbotnpm