DEV Community

Cover image for Increasing API Reliability: Adding Timeouts to Node.js Fetch
Sibelius Seraphini for Woovi

Posted on

Increasing API Reliability: Adding Timeouts to Node.js Fetch

When consuming external APIs and services you need to ensure they won't cause trouble to other parts of your system.

When an external API is down, you can try to switch to another provider if you have a fallback.

When an API is very slow, you can't be sure if the API is down or just too slow.

Adding timeout to external APIs

My recommendation is to have a timeout limit when calling any external API.

export class TimeoutError extends Error {
  constructor(message) {
    super(message); // (1)
    this.name = 'TimeoutError'; // (2)
  }
}

export const isTimeoutError = (err: Error) =>
  err instanceof TimeoutCallError;

export const timeout =
  (ms: number) =>
  (f: fetchFn): fetchFn =>
  (input: RequestInfo, init?: RequestInit) =>
    new Promise((resolve, reject) => {
      const controller = new AbortController();

      setTimeout(() => {
        reject(new TimeoutError(prettyFormat({ ...(init ?? {}) })));
        controller.abort();
      }, ms);

      f(input, { ...(init ?? {}), signal: controller.signal }).then(
        resolve,
        reject,
      );
    });
Enter fullscreen mode Exit fullscreen mode

The code above creates a custom error that will be thrown when a timeout happens.
This higher-order function is just a race condition from a setTimeout and the fetch request.

The usage with fetch is like this:

const TIMEOUT = 10000; // API timeouts 10 seconds

export const fetchWithTimeout = async (...args) => {
  try {
    const response = await timeout(TIMEOUT)(fetch)(...args);

    return response;
  } catch (err) {
    const createdResponse = createResponse({
      status: 408,
      ok: false,
    });

    return createdResponse;
  }
};
Enter fullscreen mode Exit fullscreen mode

We create a new Response with the status code 408 (Request Timeout) to make it easy for the product code to handle a request timeout, without needing to handle with try-catch.

In Summary

As your services grow, you need to keep adding more and more protection to avoid incidents.
Adding a fixed timeout for all external API calls increases the reliability of your services.

What else are you using to increase the reliability of your services?


Woovi
Woovi is a Startup that enables shoppers to pay as they like. To make this possible, Woovi provides instant payment solutions for merchants to accept orders.

If you want to work with us, we are hiring!


Photo by Kenny Eliason on Unsplash

Top comments (2)

Collapse
 
mrefaie profile image
Mohamed El-Refaie

Shouldn't you clear timeout before resolving the promise?

Collapse
 
sibelius profile image
Sibelius Seraphini

correct