catchError<T, O extends ObservableInput<any>>(selector: (err: any, caught: Observable<T>) => O): OperatorFunction<T, T | ObservedValueOf<O>>
Parámetros
Retorna
OperatorFunction<T, T | ObservedValueOf<O>>: Un Observable que se puede originar en el Observable fuente o en el Observable retornado por la función selector.
Descripción
catchError captura errores en el Observable fuente, manejándolos de dos maneras posibles: bien devolviendo un Observable nuevo o bien lanzando un nuevo error.
import { throwError, of } from "rxjs";
import { catchError } from "rxjs/operators";
const error$ = throwError("Oh no!");
error$
.pipe(
catchError((error) => {
throw `Lanzando un nuevo error: ${error}`;
})
)
.subscribe(console.log, console.error);
// Salida: (Error) Lanzando un nuevo error: Oh no!
Capturar los errores de un Observable interno
Al capturar los errores que ocurren en un Observable interno (un Observable emitido por un Observable de orden superior), se debe tener cuidado a la hora de utilizar el operador catchError ya que, si se coloca en el sitio equivocado, el flujo del Observable fuente no seguirá ejecutándose tras capturar el error.
A continuación, se puede ver cómo el uso incorrecto de catchError hará que, después de capturar el error que devuelve la primera petición, el flujo se completará y no se harán las otras dos peticiones restantes:
import { map, concatMap, catchError } from "rxjs/operators";
import { ajax } from "rxjs/ajax";
import { of } from "rxjs";
const pokemonId$ = of(-3, 5, 6);
function getPokemonName(id: number) {
return ajax
.getJSON(`https://pokeapi.co/api/v2/pokemon/${id}`)
.pipe(map(({ name }) => name));
}
pokemonId$
.pipe(
concatMap((id) => getPokemonName(id)),
catchError((error) => of(`¡Oh no, ha ocurrido un error! ${error}`))
)
.subscribe(console.log, console.error, () => console.log("Completado"));
// Salida: ¡Oh no, ha ocurrido un error! AjaxError: ajax error 404, Completado
Sin embargo, si se utiliza catchError en el Observable interno, el comportamiento es el que se busca: cuando falle la primera petición, se capturará el error y el flujo seguirá ejecutándose, realizando las dos peticiones restantes: