Observable: catch() method

Limited availability

This feature is not Baseline because it does not work in some of the most widely-used browsers.

Experimental: This is an experimental technology
Check the Browser compatibility table carefully before using this in production.

The catch() method of the Observable interface returns a new observable that replaces an error from the source observable with values from another observable.

Syntax

js
catch(callback)

Parameters

callback

A function to execute when the source observable errors. It must return a value that can be converted to an observable by Observable.from(): an Observable, a Promise, an iterable object, or an async iterable object. The function is called with the following argument:

error

The error from the source observable.

Return value

A new Observable. When subscribed to, it emits the source observable's values until the source errors, then calls callback and emits values from the observable converted from its return value. It completes when the source completes without an error, or when the replacement observable completes.

Description

Like other observable-returning operators, this method is lazy: calling it creates a new observable without subscribing to the source. Processing starts when the returned observable is subscribed to.

If callback throws an exception or its return value cannot be converted to an observable, the returned observable errors. Errors from the replacement observable are also forwarded; they do not call callback again.

catch() does not resume the source subscription or retry it automatically. The source subscription has already ended when callback runs. To handle an error from one inner observable while continuing to receive source values, place catch() inside the mapper passed to flatMap() or switchMap().

Examples

Handling errors in an inner observable

This example reports the distance dragged until it exceeds 100 pixels. The error handler ends the current drag's stream while allowing future drags to start.

js
const target = document.querySelector("div");
const output = document.querySelector("p");

target
  .when("mousedown")
  .switchMap((start) =>
    document
      .when("mousemove")
      .takeUntil(document.when("mouseup"))
      .map((move) => {
        const distance = Math.hypot(
          move.clientX - start.clientX,
          move.clientY - start.clientY,
        );
        if (distance > 100) {
          throw new Error("Too far! Start a new drag.");
        }
        return distance;
      })
      .catch((error) => {
        output.textContent = error.message;
        return [];
      }),
  )
  .subscribe((distance) => {
    output.textContent = `Distance: ${Math.round(distance)} pixels`;
  });

Placing catch() inside switchMap() keeps the error within the inner stream. The empty array completes that stream without emitting another value.

Specifications

Specification
Observable
# dom-observable-catch

Browser compatibility

See also