Gestión de Errores#
En JavaScript, es crucial capturar y manejar errores para asegurar que el código continúe funcionando adecuadamente, incluso cuando algo falla. En este capítulo, exploraremos cómo manejar errores utilizando diferentes métodos y técnicas disponibles en JavaScript.
Cuando algo falla en JavaScript, el hilo de ejecución se detiene y deja de funcionar. Para evitar que esto ocurra, es posible capturar y manejar errores conocidos.
Objeto Error#
Cuando algo falla, se lanza un objeto Error. Este objeto contiene propiedades específicas como message
, name
, fileName
, lineNumber
, columnNumber
, y stack
. Además, tiene un método útil llamado toString()
.
Es posible lanzar errores personalizados utilizando el constructor de Error. Aunque Error
es genérico, también existen errores más específicos como EvalError
, InternalError
, SyntaxError
, RangeError
, TypeError
y URIError
.
try {
throw new Error('¡Ups!')
} catch (e) {
console.error(e.name + ': ' + e.message)
}
Error: ¡Ups!
Manejar Errores#
Los errores pueden ser manejados de forma genérica o específica usando instanceof
. Además, es posible crear errores personalizados. Si es necesario ejecutar código independientemente de si ocurre un error, se utiliza finally()
.
try {
foo.bar();
} catch (e) {
console.error(e.toString());
if (e instanceof EvalError) {
console.error(e.name + ': ' + e.message);
} else if (e instanceof RangeError) {
console.error(e.name + ': ' + e.message);
} // ... etc
} finally {
closeMyFile();
}
ReferenceError: foo is not defined
Stack trace:
ReferenceError: closeMyFile is not defined
at <anonymous>:11:3
Errores en Promesas#
Cuando una promesa no puede ser cumplida, se ejecuta la función reject()
, la cual puede ser capturada en el bloque .catch()
. Sin embargo, los errores en promesas no pueden ser capturados directamente con try...catch
debido a que .catch()
siempre retorna otra promesa.
let promesa3 = new Promise(function promesa(resolve, reject) {
try {
if (Math.random() > 0.5) resolve('Funciona 3');
else throw new Error('No funciona 3');
} catch (error) {
reject(error.message);
}
});
promesa3.then(function r(message) {
console.log(message);
}).catch(function c(error) {
throw new Error(error);
}).catch(function c(error) {
console.error(error.toString());
});
Error: No funciona 3
Promise { undefined }
Errores en Async/Await#
Cuando se utiliza async/await
, se pueden manejar errores dentro de un bloque try...catch
. Si una promesa es rechazada (reject
), await
lanza un error que puede ser capturado con catch
.
async function getData(url) {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`Error de servidor: ${response.status} ${response.statusText}`);
}
const data = await response.json();
return data;
} catch (error) {
console.error('Error:', error.message);
throw error;
}
}
async function fetchExample() {
const url = 'https://api.foo.com/data';
try {
const data = await getData(url);
console.log('Datos recibidos:', data);
} catch (error) {
console.error('Error en la solicitud:', error);
}
}
fetchExample();
Promise { <pending> }
Errores en Observables#
Los Observables pueden manejar errores ejecutando la función error()
del Observer. Además, pueden retornar un error usando throwError()
y este error puede ser capturado con catchError()
dentro de las pipes.
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
const observable = new Observable(subscriber => {
try {
subscriber.next('Next value');
throw new Error('Something went wrong');
} catch (error) {
subscriber.error(error);
}
});
observable.pipe(
catchError(error => {
console.error('Caught error:', error);
return throwError(error); // Propaga el error
})
).subscribe({
next(value) { console.log(value); },
error(err) { console.error('Error handler:', err); }
});
En caso de que un Observable falle, es posible reintentar una cantidad limitada de veces utilizando retry()
.
import { retry } from 'rxjs/operators';
observable.pipe(
retry(3),
catchError(error => {
console.error('Caught error after retries:', error);
return throwError(error);
})
).subscribe({
next(value) { console.log(value); },
error(err) { console.error('Error handler:', err); }
});