Manejo de Errores
Manejo de Errores Fundamental
Section titled “Manejo de Errores ”Try…Catch Básico
Section titled “Try…Catch ”Sintaxis básica
Section titled “Sintaxis básica”try { // Código que puede lanzar un error const resultado = funcionPeligrosa();} catch (error) { // Manejar el error console.error('Ocurrió un error:', error);} finally { // Se ejecuta siempre limpiarRecursos();}Tipos de errores
Section titled “Tipos de errores”// Error genéricothrow new Error('Algo salió mal');
// Tipos específicos de errorthrow new TypeError('Tipo incorrecto');throw new ReferenceError('Variable no definida');throw new RangeError('Valor fuera de rango');throw new SyntaxError('Sintaxis inválida');Errores personalizados Importante
Section titled “Errores personalizados ”Crear clases de error
Section titled “Crear clases de error”class ValidationError extends Error { constructor(message) { super(message); this.name = 'ValidationError'; }}
class DatabaseError extends Error { constructor(message, query) { super(message); this.name = 'DatabaseError'; this.query = query; }}
// Usofunction validarEdad(edad) { if (typeof edad !== 'number') { throw new ValidationError('La edad debe ser un número'); } if (edad < 0 || edad > 120) { throw new ValidationError('Edad fuera de rango válido'); }}Manejo asíncrono Importante
Section titled “Manejo asíncrono ”Promesas
Section titled “Promesas”function obtenerDatos() { return fetch('/api/datos') .then(response => { if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return response.json(); }) .catch(error => { console.error('Error al obtener datos:', error); throw error; // Re-lanzar para manejo superior });}Async/Await
Section titled “Async/Await”async function obtenerDatos() { try { const response = await fetch('/api/datos'); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return await response.json(); } catch (error) { console.error('Error al obtener datos:', error); throw error; }}Patrones de manejo de errores Avanzado
Section titled “Patrones de manejo de errores ”Error boundary
Section titled “Error boundary”class ErrorBoundary { constructor() { this.errors = []; }
execute(fn) { try { return fn(); } catch (error) { this.handleError(error); return null; } }
async executeAsync(fn) { try { return await fn(); } catch (error) { this.handleError(error); return null; } }
handleError(error) { this.errors.push({ timestamp: new Date(), error: error }); // Implementar lógica de manejo de errores console.error('Error capturado:', error); }}
// Usoconst errorBoundary = new ErrorBoundary();errorBoundary.execute(() => { // Código que puede fallar});Manejo centralizado
Section titled “Manejo centralizado”const ErrorHandler = { handlers: new Map(),
register(errorType, handler) { this.handlers.set(errorType, handler); },
handle(error) { const handler = this.handlers.get(error.constructor) || this.handlers.get('default');
if (handler) { return handler(error); }
throw error; // Si no hay handler }};
// Registrar handlersErrorHandler.register(ValidationError, (error) => { console.error('Error de validación:', error.message); // Mostrar mensaje al usuario});
ErrorHandler.register(DatabaseError, (error) => { console.error('Error de base de datos:', error.message); // Intentar reconectar});
ErrorHandler.register('default', (error) => { console.error('Error no manejado:', error); // Notificar al sistema de monitoreo});Mejores prácticas Recomendado
Section titled “Mejores prácticas ”Granularidad en el manejo
Section titled “Granularidad en el manejo”// ❌ Malo - Catch demasiado generaltry { hacerAlgo();} catch (error) { console.error(error);}
// ✅ Bueno - Manejo específicotry { hacerAlgo();} catch (error) { if (error instanceof ValidationError) { mostrarErrorValidacion(error); } else if (error instanceof DatabaseError) { manejarErrorDB(error); } else { // Error no esperado notificarError(error); throw error; }}Logging efectivo
Section titled “Logging efectivo”function logError(error, context = {}) { const errorInfo = { timestamp: new Date().toISOString(), name: error.name, message: error.message, stack: error.stack, ...context };
// En desarrollo if (process.env.NODE_ENV === 'development') { console.error('Error:', errorInfo); }
// En producción if (process.env.NODE_ENV === 'production') { // Enviar a servicio de logging enviarAServicioLogging(errorInfo); }}Recuperación elegante
Section titled “Recuperación elegante”class ServicioAPI { async obtenerDatos(id, opciones = {}) { const { reintentos = 3, esperaMS = 1000 } = opciones;
for (let intento = 1; intento <= reintentos; intento++) { try { return await this.llamadaAPI(id); } catch (error) { if (error.response?.status === 429) { // Rate limiting - esperar y reintentar await new Promise(r => setTimeout(r, esperaMS * intento)); continue; }
if (intento === reintentos) { throw new APIError( 'Máximo de reintentos alcanzado', { causa: error, intentos: intento } ); } } } }}
🐝