Cómo manejar errores de red en el frontend sin mala UX
- frontend
- ux
- software
- desarrollo
- api
Cuando una aplicación frontend se comunica con un backend, los errores de red son una realidad inevitable. No se trata de evitarlos por completo — eso es imposible — sino de gestionarlos de forma que el usuario no se sienta frustrado ni abandone la aplicación. Un spinner eterno o una pantalla en blanco después de un fetch fallido son la receta para una mala experiencia.
Mi regla es simple: el usuario siempre debe entender qué está pasando y, si es posible, tener una opción para intentar resolverlo.
Por qué los errores de red son más críticos en frontend
En el backend, un error de red suele ser un problema de infraestructura que se maneja con logs y alertas internas. En el frontend, es un problema de usabilidad directo. El usuario lo ve, lo sufre, y si no le das una alternativa, se va.
Los fallos de red pueden venir de muchos sitios: la conexión a internet del usuario, un servidor caído, un problema en la API o incluso un bloqueo de CORS. No podemos controlar la mayoría de estas causas, pero sí cómo reacciona nuestra aplicación.
Estrategias de manejo de errores de red que funcionan
La clave es anticiparse y ofrecer alternativas. El usuario no quiere saber por qué falló, quiere saber qué hacer o que la aplicación se recupere sola.
Reintentos con backoff exponencial
Cuando una llamada fetch falla por un error transitorio de red, un simple reintento puede solucionar el problema. Pero reintentar inmediatamente en bucle puede empeorar la situación si el servidor está saturado.
Un backoff exponencial es lo que uso en estos casos. Consiste en esperar un tiempo cada vez mayor entre reintentos. Esto permite que el servidor se recupere y evita saturarlo aún más. Aquí un ejemplo básico:
async function fetchWithRetry(url, options = {}, retries = 3, delay = 1000) {
try {
const response = await fetch(url, options);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response;
} catch (error) {
if (retries > 0) {
console.warn(`Fetch fallido, reintentando en ${delay / 1000}s...`, error);
await new Promise(resolve => setTimeout(resolve, delay));
return fetchWithRetry(url, options, retries - 1, delay * 2);
}
throw error;
}
}
// Uso
fetchWithRetry('/api/data')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error final:', error.message));
Este patrón no solo mejora la robustez, sino que también evita que un problema puntual se convierta en un error visible para el usuario. Para asegurar que tu backend es igual de robusto, es importante que el diseño de tu API REST sea correcto y que maneje sus propios errores adecuadamente.
Caching y datos stale-while-revalidate
No siempre es necesario mostrar un error cuando no se puede obtener la última versión de los datos. Si los datos no son críticos o se actualizan con poca frecuencia, puedes mostrar la versión en caché y, en segundo plano, intentar actualizarla. Esto se conoce como el patrón stale-while-revalidate.
El usuario ve datos, aunque no sean los más frescos, y la aplicación intenta actualizar de forma transparente. Si el reintento falla, el usuario sigue viendo algo útil en lugar de un error. La decisión de cuándo usar caché en aplicaciones web es clave para implementar esto bien.
Feedback claro y opciones al usuario
Cuando un error es persistente, la aplicación debe comunicarlo de forma clara. Mensajes como “No se pudo cargar la información. Revisa tu conexión o inténtalo de nuevo.” son mucho mejores que un spinner infinito.
Lo que sí debe tener un buen mensaje de error:
- Claridad: Qué falló, sin tecnicismos.
- Acción: Qué puede hacer el usuario (reintentar, revisar conexión).
- Contexto: Si es un error crítico o solo afecta a una parte.
Incluir un botón para “Reintentar” es una forma directa de empoderar al usuario. Un buen diseño de sistema de notificaciones puede ser el aliado perfecto para comunicar estos errores sin ser intrusivo.
Ventajas y desventajas de las estrategias de manejo de errores de red
Implementar un manejo de errores robusto en el frontend implica decisiones y compromisos.
Lo que ganas:
- Mejora drástica de la experiencia de usuario ante fallos de red.
- Mayor resiliencia de la aplicación, que se siente más robusta.
- Reducción de la frustración del usuario, lo que se traduce en mayor retención.
Lo que complicas:
- Mayor complejidad en el código del frontend, especialmente con lógicas de reintento y caché.
- Necesidad de una buena gestión del estado de la UI (cargando, error, datos antiguos).
- Mayor tiempo de desarrollo inicial para cubrir estos casos.
Un frontend que no considera los errores de red como parte del flujo normal de la aplicación es un frontend frágil. La inversión en este tipo de lógica es siempre rentable a largo plazo.
Si estás trabajando con lógica asíncrona en el frontend, es importante que entiendas los errores comunes de async/await en JavaScript para evitar problemas. Además, para asegurar la calidad de tu código y reducir los errores desde el principio, considera implementar testing automatizado en tus proyectos.
Técnico freelance especializado en desarrollo a medida, automatizaciones con IA y gestión técnica para negocios en España. Más sobre mí →
¿Necesitas desarrollo a medida?
Desarrollo funcionalidades específicas, integraciones entre sistemas y herramientas internas. Si se puede programar, probablemente puedo hacerlo.