WDK logoWDK documentation

Failover Provider Configuration

Install @tetherto/wdk-failover-provider and configure retries, retry predicates, and provider candidates

This page shows how to install @tetherto/wdk-failover-provider, configure retries and shouldRetryOn, and build a proxied provider with addProvider() and initialize().

Install the package

You can install the package from npm:

Install @tetherto/wdk-failover-provider
npm install @tetherto/wdk-failover-provider

Create a failover provider

You can wrap any provider-like object type. This example uses plain objects so the retry behavior is easy to see:

Create A Failover Provider
import FailoverProvider from '@tetherto/wdk-failover-provider'

const primary = {
  name: 'primary',
  async getBlockNumber () {
    throw new Error('temporary upstream outage')
  }
}

const secondary = {
  name: 'secondary',
  async getBlockNumber () {
    return 21345678
  }
}

const provider = new FailoverProvider({
  retries: 1,
  shouldRetryOn: (error) =>
    error instanceof Error && error.message.includes('temporary')
})
  .addProvider(primary)
  .addProvider(secondary)
  .initialize()

Configuration options

retries

retries controls how many additional attempts happen after the first failure. The published runtime defaults to 3, which means a call can make up to 1 + retries total attempts before the latest error is thrown.

shouldRetryOn

shouldRetryOn(error) decides whether a thrown error or rejected promise should advance to the next provider. The published default retries on any Error instance.

Use a narrow predicate when you only want to retry transient failures:

Retry Only On Transient Errors
const provider = new FailoverProvider({
  retries: 2,
  shouldRetryOn: (error) =>
    error instanceof Error && /timeout|temporary|429/.test(error.message)
})

Register provider candidates

Call addProvider(provider) once per candidate before you call initialize(). addProvider() returns the same FailoverProvider instance, so you can chain the calls.

The generic type T applies to every added candidate, so keep the provider shape consistent across the chain.

Add Multiple Provider Candidates
const provider = new FailoverProvider({ retries: 2 })
  .addProvider(primary)
  .addProvider(secondary)
  .addProvider({
    name: 'tertiary',
    async getBlockNumber () {
      return 21345679
    }
  })
  .initialize()

Initialize the proxy

Call initialize() after you have added at least one provider. The returned value is a proxied provider of type T.

The runtime throws if you call initialize() before adding any providers:

Initialize Requires At Least One Provider
const factory = new FailoverProvider()

factory.initialize()
// Error: Cannot initialize an empty provider. Call `addProvider` before this function.

Runtime notes

  • Non-function properties are read from the currently active provider.
  • Property getters and methods run with the underlying provider as this, including providers that use private fields or instance state.
  • When a synchronous method throws and shouldRetryOn(error) returns true, the proxy switches to the next provider and retries.
  • When an asynchronous method rejects and shouldRetryOn(error) returns true, the proxy switches to the next provider and retries.
  • A method result is treated as asynchronous only when its then property is a function. Other values, including objects with a non-function then property, are returned synchronously.
  • Provider selection advances in round-robin order. If retries is larger than the number of providers, the runtime loops back through the list.

Use the initialized proxy for property reads and method calls. Writes, enumeration, and property-descriptor operations apply to the proxy target rather than the active provider.


Need Help?

On this page