Frase célebre en los equipos junior: no hay bugs si capturas absolutamente todo. Yo también viví con esa ilusión hasta que me cansé de rodear cada fetch con try catch.
Después de lanzar decenas de aplicaciones en React vi el mismo patrón repetirse en cada petición HTTP: try catch, verificar res.ok, gestionar timeouts, cruzar los dedos para que la API devuelva lo esperado. Acabábamos depurando manejadores de errores más tiempo del que dedicábamos a crear funcionalidades.
La gota que colmó el vaso fue un arreglo crítico a las dos de la madrugada. Un rechazo de promesa sin manejar tumbó el panel porque alguien olvidó envolver un fetch. Entonces lo entendí: el problema no es que gestionemos mal los errores, el problema es que fetch nos obliga a gestionarlos en todas partes y en todo momento.
No tiene por qué ser así. Por eso nació @asouei safe fetch, con el objetivo de eliminar para siempre el try catch en las peticiones HTTP.
Historia desde las trincheras: integrábamos tres APIs en un proyecto para cliente. Sobre el papel, fácil. En la realidad, la pasarela de pagos devolvía 500 de forma aleatoria en horas punta, el servicio de usuarios respondía con objeto vacío y estado 200, el endpoint de analítica se colgaba 30 segundos y los usuarios pensaban que nuestra app estaba rota, mientras los logs se llenaban de mensajes poco útiles de fallo de solicitud.
El código se convirtió en un espagueti de manejo de errores. Cada función repetía el mismo patrón con try catch. En revisiones de código, la pregunta recurrente era comprobaste res.ok.
Seis meses después usando safe fetch, todo cambió. Centralizamos el manejo de errores con interceptores y pasamos a depurar en un único lugar. Los reintentos automáticos en GET curaron APIs inestables. Los timeouts globales eliminaron peticiones colgadas. Los logs se volvieron expresivos con nombres como NetworkError y TimeoutError. Y, lo más importante, dejamos de escribir try catch alrededor de cada llamada HTTP. La productividad subió de inmediato.
Dolores habituales con fetch: solo lanza en fallos de red, los estados 404 o 500 hay que revisarlos a mano, no trae timeouts incorporados y terminas usando AbortController por todos lados, los errores no tienen tipo y te quedas adivinando el contenido de error.message, la lógica de reintentos hay que implementarla desde cero o sumas otra librería, y el boilerplate se copia y pega por toda la base de código.
Qué propone safe fetch. Uno, sin excepciones en la capa de consumo, siempre devuelve un resultado con bandera ok para evitar sorpresas. Dos, errores tipados con categorías claras como NetworkError, TimeoutError, HttpError y ValidationError. Tres, capacidades de producción listas desde el primer día: timeouts globales, reintentos inteligentes con backoff, soporte de cabecera Retry After e interceptores para solicitud y respuesta. El resultado es siempre predecible, o bien ok verdadero con los datos, o bien ok falso con un error. La lógica de negocio queda limpia, sin try catch.
Antes y después. Antes, cada método HTTP repetía el mismo bloque try catch, comprobación manual de res.ok, parseo y logging, multiplicado por decenas de endpoints. Después, una única instancia creada con createSafeFetch define baseURL, timeout, estrategia de reintentos e interceptores para autenticar, medir y registrar. Los métodos api.get y api.post devuelven un resultado seguro y el uso es consistente en toda la app.
Funciones clave que resuelven problemas reales. Timeouts duales: uno por intento y otro total sumando reintentos para mantener el control de la latencia. Reintentos inteligentes que por defecto solo aplican a GET y HEAD, evitando duplicar operaciones no idempotentes, con backoff exponencial configurable y respeto automático de la cabecera Retry After cuando el servidor devuelve 429. Validación segura de datos mediante esquemas, de forma que si la estructura no coincide, recibes un ValidationError y tu result.data solo existe y está tipado cuando ok es verdadero.
Migración sencilla. Donde antes escribías try catch, ahora recibes un resultado. Si ok es verdadero, usas los datos. Si es falso, la rama de error te indica con precisión qué hacer, desde mostrar un botón de reintentar hasta enseñar un estado no encontrado. Funciona sin fricción con Next.js, Vite, Create React App, Node.js y Cloudflare Workers.
Tamaño de bundle. safe fetch ronda los 3 kb comprimido, muy por debajo de alternativas más pesadas como axios o ky, y te ofrece resultados seguros, errores tipados, reintentos y timeout global, cosas que fetch por sí solo no aporta.
Primeros pasos. Instala el paquete con npm install @asouei/safe-fetch. Crea una instancia con createSafeFetch, define tu baseURL, timeouts y reintentos, y consume los endpoints con api.get o api.post. Comprueba la propiedad ok del resultado y actúa en consecuencia.
Para quién es. Equipos cansados de repetir manejo de errores. Aplicaciones en producción que necesitan timeouts y reintentos confiables. Proyectos TypeScript que buscan tipos precisos y validación de datos. Desarrolladores que aman la simplicidad de fetch y quieren capacidades de nivel empresarial sin añadir complejidad.
Qué viene después. Plugin de ESLint para reforzar patrones de error handling seguro, adaptadores para React Query y SWR, y guías específicas para Next.js App Router, Remix y SvelteKit.
Pruébalo. safe fetch no intenta reinventar los clientes HTTP. Resuelve un problema muy concreto: hacer que fetch se comporte de forma predecible en apps de producción, eliminando la fricción diaria de escribir el mismo patrón una y otra vez. El proyecto ha recibido reconocimiento en la comunidad de TypeScript y forma parte de listados curados de calidad. Puedes ver el código y ejemplos en el repositorio en GitHub o instalarlo desde su paquete en npm.
En Q2BSTUDIO impulsamos este tipo de buenas prácticas en desarrollo con aplicaciones a medida y software a medida, integrando patrones de error handling seguros, servicios cloud aws y azure, ciberseguridad desde el diseño y servicios inteligencia de negocio con power bi. Si tu empresa busca elevar su stack técnico con ia para empresas y agentes IA en procesos críticos, descubre cómo lo hacemos en nuestro servicio de desarrollo de aplicaciones a medida y en nuestra práctica de inteligencia artificial.
Conclusión. Dejar de envolver cada fetch en try catch libera a tu equipo para centrarse en aportar valor. Con resultados seguros, errores tipados y políticas de tiempo y reintentos coherentes, tu frontend gana resiliencia, tu observabilidad mejora y tu roadmap avanza más rápido, con menos bugs y más foco en lo que importa.