El manejo de errores es una parte crucial del desarrollo de aplicaciones robustas y confiables. En este tema, aprenderemos cómo manejar errores en una aplicación Express.js, asegurándonos de que nuestra aplicación pueda responder adecuadamente a situaciones inesperadas y proporcionar información útil para la depuración.
Conceptos Clave
- Errores Sincrónicos vs. Asincrónicos: Entender la diferencia entre errores que ocurren en código sincrónico y asincrónico.
- Middleware de Manejo de Errores: Cómo crear y utilizar middleware específico para manejar errores en Express.
- Propagación de Errores: Técnicas para propagar errores a través de la aplicación.
- Manejo de Errores en Promesas y Async/Await: Estrategias para manejar errores en código asincrónico.
Errores Sincrónicos vs. Asincrónicos
Errores Sincrónicos
Los errores sincrónicos ocurren en el flujo normal de ejecución del código. Estos pueden ser capturados utilizando bloques try...catch
.
try { // Código que puede lanzar un error let result = someFunction(); } catch (error) { console.error('Error sincrónico:', error); }
Errores Asincrónicos
Los errores asincrónicos ocurren en operaciones que no se ejecutan inmediatamente, como callbacks, promesas y funciones async/await
.
Callbacks
fs.readFile('somefile.txt', (err, data) => { if (err) { console.error('Error asincrónico (callback):', err); return; } console.log(data); });
Promesas
someAsyncFunction() .then(result => { console.log(result); }) .catch(error => { console.error('Error asincrónico (promesa):', error); });
Async/Await
async function asyncFunction() { try { let result = await someAsyncFunction(); console.log(result); } catch (error) { console.error('Error asincrónico (async/await):', error); } }
Middleware de Manejo de Errores
Express proporciona una forma sencilla de manejar errores mediante middleware. Un middleware de manejo de errores es una función que tiene cuatro parámetros: err
, req
, res
, y next
.
Ejemplo de Middleware de Manejo de Errores
const express = require('express'); const app = express(); // Middleware de manejo de errores app.use((err, req, res, next) => { console.error(err.stack); res.status(500).send('Algo salió mal!'); }); // Ruta que lanza un error app.get('/', (req, res) => { throw new Error('Error intencional'); }); app.listen(3000, () => { console.log('Servidor escuchando en el puerto 3000'); });
Propagación de Errores
Para propagar errores a través de la aplicación, podemos pasar el error al siguiente middleware utilizando next(err)
.
app.get('/user/:id', (req, res, next) => { let userId = req.params.id; if (!userId) { let err = new Error('ID de usuario no proporcionado'); err.status = 400; return next(err); } // Lógica para manejar la solicitud });
Manejo de Errores en Promesas y Async/Await
Promesas
app.get('/data', (req, res, next) => { someAsyncFunction() .then(data => { res.send(data); }) .catch(next); // Propaga el error al middleware de manejo de errores });
Async/Await
app.get('/data', async (req, res, next) => { try { let data = await someAsyncFunction(); res.send(data); } catch (error) { next(error); // Propaga el error al middleware de manejo de errores } });
Ejercicio Práctico
Ejercicio
- Crea una aplicación Express que tenga una ruta
/error
que lance un error intencional. - Implementa un middleware de manejo de errores que capture cualquier error y devuelva una respuesta JSON con el mensaje de error y el código de estado HTTP 500.
Solución
const express = require('express'); const app = express(); // Ruta que lanza un error intencional app.get('/error', (req, res) => { throw new Error('Error intencional'); }); // Middleware de manejo de errores app.use((err, req, res, next) => { console.error(err.stack); res.status(500).json({ message: 'Algo salió mal!', error: err.message }); }); app.listen(3000, () => { console.log('Servidor escuchando en el puerto 3000'); });
Resumen
En esta sección, hemos aprendido sobre el manejo de errores en Express.js, incluyendo la diferencia entre errores sincrónicos y asincrónicos, cómo crear middleware de manejo de errores, y cómo propagar errores a través de la aplicación. También hemos visto cómo manejar errores en promesas y funciones async/await
. Con estas técnicas, puedes asegurarte de que tu aplicación sea más robusta y fácil de depurar.
Curso de Node.js
Módulo 1: Introducción a Node.js
Módulo 2: Conceptos Básicos
Módulo 3: Sistema de Archivos y E/S
Módulo 4: HTTP y Servidores Web
- Creando un Servidor HTTP Simple
- Manejo de Solicitudes y Respuestas
- Sirviendo Archivos Estáticos
- Enrutamiento
Módulo 5: NPM y Gestión de Paquetes
- Introducción a NPM
- Instalación y Uso de Paquetes
- Creación y Publicación de Paquetes
- Versionado Semántico
Módulo 6: Framework Express.js
- Introducción a Express.js
- Configuración de una Aplicación Express
- Middleware
- Enrutamiento en Express
- Manejo de Errores
Módulo 7: Bases de Datos y ORMs
- Introducción a las Bases de Datos
- Usando MongoDB con Mongoose
- Usando Bases de Datos SQL con Sequelize
- Operaciones CRUD
Módulo 8: Autenticación y Autorización
- Introducción a la Autenticación
- Usando Passport.js
- Autenticación JWT
- Control de Acceso Basado en Roles
Módulo 9: Pruebas y Depuración
- Introducción a las Pruebas
- Pruebas Unitarias con Mocha y Chai
- Pruebas de Integración
- Depuración de Aplicaciones Node.js
Módulo 10: Temas Avanzados
- Módulo Cluster
- Hilos de Trabajo
- Optimización del Rendimiento
- Construcción de APIs RESTful
- GraphQL con Node.js
Módulo 11: Despliegue y DevOps
- Variables de Entorno
- Usando PM2 para la Gestión de Procesos
- Desplegando en Heroku
- Integración y Despliegue Continuos