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,
);
});
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;
}
};
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)
Shouldn't you clear timeout before resolving the promise?
correct