http-fetch-retry
v3.0.0
Published
HttpClient con reintento nativo en fetch Node.js
Maintainers
Readme
http-fetch-retry
http-fetch-retry es una librería ligera para Node.js que extiende el
fetch nativo agregando:
- 🔁 Reintentos automáticos con backoff exponencial + jitter
- ⏱ Timeout por request usando AbortController
- 🧠 Manejo seguro de errores de red y timeouts
- 🧩 Compatibilidad total con
fetchnativo (retornaResponse)
⚠️ Desde v3.x,
fetchWithRetryretorna unResponsenativo y NO lanza errores por status 4xx/5xx.
Compatible con:
- Node.js 22+
- ESM
- CommonJS
- TypeScript vía
.d.ts - CI en Node 22, 24 y 26
- Publicación automática por tags
v*
Instalación
npm install http-fetch-retryUso
ESM
import { HttpClient } from 'http-fetch-retry';
const res = await HttpClient.fetchWithRetry({
method: 'GET',
url: 'https://api.example.com',
});
if (!res.ok) {
console.error('HTTP error:', res.status);
}
const data = await res.json();
console.log(data);CommonJS
const { HttpClient } = require('http-fetch-retry');
(async () => {
const res = await HttpClient.fetchWithRetry({
method: 'GET',
url: 'https://api.example.com',
});
const data = await res.json();
console.log(data);
})();API
HttpClient.fetchWithRetry(request, options)
Extiende fetch nativo agregando reintentos y timeout.
Retorna
Promise<Response> (Response nativo)
No parsea automáticamente JSON.
Parámetros
request
Entrada compatible con fetch:
{
url: string, // requerido
method?: string, // default: GET
headers?: object,
body?: BodyInit | null
}También acepta Request, URL o string directamente.
Para reintentos seguros, el body debería ser reutilizable:
string, URLSearchParams, ArrayBuffer, ArrayBufferView, Blob,
FormData o Buffer.
options
{
timeoutMs?: number, // default 30000
maxRetries?: number, // default 3
baseDelayMs?: number, // default 300
maxDelayMs?: number, // default 5000
retryStatusCodes?: number[], // default [408,429,500,502,503,504]
retryMethods?: string[], // default unrestricted unless strict; strict default GET, HEAD, OPTIONS, TRACE, PUT, DELETE
logger?: (entry) => void
onWarning?: (entry) => void
onDecision?: (entry) => void
strict?: boolean // default false
}logger recibe un evento tipado con phase:
attemptresponseretryerror
onWarning recibe eventos de normalización cuando el cliente corrige entradas
inválidas sin strict. Cada evento incluye code, field y el valor
original/fallback cuando aplica.
onDecision recibe eventos de alto nivel con la decisión final de la librería:
returnretrythrow
Y te indica si la causa fue status, method, timeout, network,
body o validation.
En strict, también reporta errores de validación antes de lanzar la excepción.
strict: true convierte entradas inválidas en errores explícitos.
Con el valor por defecto, el cliente sigue normalizando a defaults seguros.
Si defines retryMethods, la lista se usa para limitar retries.
En strict, la lista no puede estar vacía.
En strict, un body no reutilizable con reintentos habilitados falla
antes de enviar la request.
También valida method inválido, headers inválidos, Request con body ya consumido
y solo reintenta métodos listados en retryMethods si se define.
Comportamiento de Retry
Reintenta automáticamente cuando:
- Status HTTP: 408, 429, 500, 502, 503, 504
- Error de red (
TypeError) - Timeout (
AbortError) - Si existe
Retry-Afteren 429/503, se respeta como base del siguiente intento
No reintenta si:
maxRetries = 0- El
bodyno es reutilizable (ej: streams)
Timeout
Internamente usa AbortController.
Si ocurre timeout se lanza:
- FetchTimeoutError
Errores disponibles
- FetchTimeoutError
- FetchRetryError
- FetchResponseError
- HostAuthenticationError
- HostRequestTimeoutError
Todos heredan de CustomError.
Testing
npm testCobertura:
npm run test:coverageBreaking Changes
v2.0.0
fetchWithRetryahora retornaResponsenativo- Ya no parsea JSON automáticamente
- Ya no lanza error por status 4xx/5xx
- Comportamiento alineado 100% con
fetch
Migración:
Antes:
const data = await HttpClient.fetchWithRetry(...);Ahora:
const res = await HttpClient.fetchWithRetry(...);
const data = await res.json();Licencia
MIT
