Solución: UnhandledPromiseRejection — promesa rechazada sin manejar
Node.js o el navegador avisan de que una promesa falló y nadie capturó el error. Cómo identificar la promesa problemática y añadir manejo de errores correcto.
¿Por qué ocurre?
Una promesa fue rechazada (threw un error internamente o se llamó reject()) pero no tiene un .catch() ni un try/catch que lo gestione. En Node.js 15+ esto termina el proceso. En el navegador aparece como warning en la consola.
Solución paso a paso
Solución básica — añadir .catch() o try/catch:
// ❌ Sin manejo de error — la promesa puede rechazarse silenciosamente
fetch('https://api.example.com/datos')
.then(res => res.json())
.then(data => console.log(data));// ✅ Con .catch()
fetch('https://api.example.com/datos')
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.error('Error al cargar datos:', err));
// ✅ Con async/await y try/catch
async function cargarDatos() {
try {
const res = await fetch('https://api.example.com/datos');
const data = await res.json();
console.log(data);
} catch (err) {
console.error('Error al cargar datos:', err);
}
}
Caso común — Promise.all sin catch:
// ❌ Si cualquiera de las promesas falla, todo explota
const resultados = await Promise.all([
fetchUsuario(1),
fetchUsuario(2),
fetchUsuario(3),
]);// ✅ Captura el error del grupo
try {
const resultados = await Promise.all([...]);
} catch (err) {
console.error('Una de las peticiones falló:', err);
}
// ✅ O usa Promise.allSettled para que no falle aunque alguna rechace
const resultados = await Promise.allSettled([
fetchUsuario(1),
fetchUsuario(2),
]);
resultados.forEach(r => {
if (r.status === 'fulfilled') console.log(r.value);
else console.error('Falló:', r.reason);
});
Manejador global en Node.js (último recurso, para logging):
// Para loggear errores no capturados antes de que maten el proceso
process.on('unhandledRejection', (reason, promise) => {
console.error('Promesa sin manejar:', promise, 'Razón:', reason);
// En producción: enviar a Sentry, cerrar conexiones, etc.
process.exit(1); // Salir con error — no silenciar el fallo
});
Truco para encontrar la promesa problemática:
# Node.js 16+ muestra el stack trace completo con:
node --trace-warnings tu-script.js
Cómo evitarlo en el futuro
Toda función async debe tener try/catch o devolver la promesa para que quien la llame la gestione. En Express, usa un middleware de errores centralizado y asegúrate de que tus controladores async pasen los errores a `next(err)`.
¿Quieres que una IA te ayude? Genera el prompt perfecto para tu error:
Generador de Prompts