Повышение надежности API: добавление таймаутов в Node.js Fetch
При использовании внешних API и сервисов вам необходимо убедиться, что они не создадут проблем для других частей вашей системы.
Когда внешний API не работает, вы можете попробовать переключиться на другого провайдера, если у вас есть запасной вариант.
Когда API работает очень медленно, вы не можете быть уверены, что API не работает или он слишком медленный.
Добавление таймаута к внешним API
Я рекомендую установить ограничение по времени ожидания при вызове любого внешнего 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,
);
});
Приведенный выше код создает пользовательскую ошибку, которая будет выдана при истечении времени ожидания.
Эта функция высшего порядка — это просто состояние гонки из setTimeout
и запроса fetch
.
Использование с fetch
выглядит следующим образом:
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;
}
};
Мы создаем новый Response
с кодом состояния 408
(время ожидания запроса), чтобы код мог легко обрабатывать тайм-аут запроса без необходимости обработки с помощью try-catch
.
В итоге
По мере роста ваших услуг вам необходимо постоянно добавлять все больше и больше защиты, чтобы избежать инцидентов.
Добавление фиксированного тайм-аута для всех внешних вызовов API повышает надежность ваших сервисов.
Что еще вы используете для повышения надежности своих услуг?