---
title: Handling Errors with RxJS
description: "Handling errors gracefully gives your users a better experience. Learn useful RxJS error handling operators: catch and catchError, retry, and retryWhen."
image: https://www.bitovi.com/hubfs/Table%20with%20Sweet%20Brigadeiro%20-%20Its%20typical%20in%20Brazil.jpeg
---

- ![AI implementation](https://www.bitovi.com/hubfs/AIConsultingIcon.svg)
  
  [AI implementation](https://www.bitovi.com/services/ai-consulting)
- ![Systems engineering](https://www.bitovi.com/hubfs/icon%20-%20backend.svg)
  
  [Systems engineering](https://www.bitovi.com/services/systems-engineering-consulting)
- ![Project Management](https://www.bitovi.com/hubfs/icon%20-%20PM.svg)
  
  [Project Management](https://www.bitovi.com/services/agile-project-management-consulting)
- ![Product Design](https://www.bitovi.com/hubfs/icon%20-%20design.svg)
  
  [Product Design](https://www.bitovi.com/services/product-design-consulting)
- ![Frontend development](https://www.bitovi.com/hubfs/icon%20-%20frontend.svg)
  
  [Frontend development](https://www.bitovi.com/services/frontend-development-consulting)
- [View more
  
  →
  
  ](https://www.bitovi.com/digital-consulting-services)

We're Experts in...

- [JavaScript](https://www.bitovi.com/services/frontend/javascript-consulting)
- [AI training](https://www.bitovi.com/ai-training-for-software-engineers)
- [Angular](https://www.bitovi.com/services/frontend/angular-consulting)
- [Design systems](https://www.bitovi.com/services/axure-figma-migration)
- [React](https://www.bitovi.com/services/frontend/react-consulting)
- [Temporal](https://www.bitovi.com/services/backend/temporal-consulting)
- [React Native](https://www.bitovi.com/services/frontend/react-consulting/react-native)
- [Node.js](https://www.bitovi.com/services/backend/nodejs-consulting)

Showcase

![Yum! Brands](https://www.bitovi.com/hubfs/yum-showcase-link-1.png)

[View case study](https://www.bitovi.com/en/bitovi-yum-case-study)

More Projects

- [![Levi's](https://www.bitovi.com/hubfs/levis.svg)](https://www.bitovi.com/web-application-consulting-work/levis-ecommerce-responsive-redesign)
- [![Christie's International Real Estate](https://www.bitovi.com/hubfs/christies.svg)](https://design.bitovi.com/christies)
- [![BAFS](https://www.bitovi.com/hubfs/bafs.svg)](https://www.bitovi.com/ux-design-consulting/ux-case-studies/bafs-ppp)
- [View more
  
  →
  
  ](https://www.bitovi.com/our-software-consulting-work)

Open Source Tools

We build powerful tools and open source them to support the community.

[See what we've built →](https://www.bitovi.com/open-source)

- [![Blog](https://www.bitovi.com/hubfs/icon%20-%20blog.svg)
  
  BlogWe post about delivering products and solving problems.
  
  ](https://www.bitovi.com/blog)
- [![Partnerships](https://www.bitovi.com/hubfs/Handshake-1.svg)
  
  PartnershipsLearn about Bitovi's technology partners
  
  ](https://www.bitovi.com/partnerships)
- [![Academy](https://www.bitovi.com/hubfs/icon%20-%20academy%20(4).svg)
  
  AcademyFree courses to build delivery skills
  
  ](https://www.bitovi.com/academy)
- [![Open source tools](https://www.bitovi.com/hubfs/icon%20-%20open%20source.svg)
  
  Open source toolsUse or contribute to our community
  
  ](https://www.bitovi.com/open-source)

Let's Connect

- [![Discord](https://www.bitovi.com/hubfs/DiscordLogo.svg)
  
  Discord
  
  ](https://discord.gg/J7ejFsZnJ4)
- [![LinkedIn](https://www.bitovi.com/hubfs/LinkedinLogo.svg)
  
  LinkedIn
  
  ](https://www.linkedin.com/company/bitovi/)
- [![GitHub](https://www.bitovi.com/hubfs/GithubLogo.svg)
  
  GitHub
  
  ](https://github.com/bitovi/)

![Eggbot](https://www.bitovi.com/hubfs/build_assets/bitovi-limbo-cms-react/338/js_client_assets/assets/eggbot-LTGhdSGL.png)

Name *

Work Email *

Phone

What's your project?

Send

### Contact Us

(312) 620-0386contact@bitovi.com

[ Angular ](https://www.bitovi.com/blog/topic/angular) |  February 22, 2022

# Handling Errors with RxJS

 Handling errors gracefully gives your users a better experience. Learn useful RxJS error handling operators: catch and catchError, retry, and retryWhen.

![Adrian Ferguson](https://www.bitovi.com/hubfs/adrian-ferguson.png)

 Adrian Ferguson

Share:

[![Twitter](https://www.bitovi.com/hubfs/limbo-generated/_astro/twitter-white.os3xLc3C_Z2nW4or.svg) ](https://twitter.com/intent/tweet?text=) [![Reddit](https://www.bitovi.com/hubfs/limbo-generated/imgs/icons/reddit.png) ](http://reddit.com/submit?url=)

In [Angular](https://www.bitovi.com/why-build-with-angular) and other modern web frameworks, the UI is so intertwined that one unexpected response from the server can turn a beautiful website into a blank screen. Fortunately, you can build in error handling to help avoid this terrible scenario.

By error handling  I mean responding and recovering from errors that are likely an API returning an error or an unexpected response.

There are many JavaScript libraries you can use to handle errors. One of the most popular libraries is [RxJS](https://rxjs.dev/) (short for Reactive Extensions Library for JavaScript).

## RxJS Operators for Handling Errors

RxJS has operators designed to help you handle errors. Read on to learn these useful ones: `catch`and`catchError`, `retry`, and `retryWhen`.

`catch` and `catchError` are used in more general situations. `retry` and `retryWhen` can be geared more towards specific errors that need special handling.

## catch and catchError

I'll start with `catch` and `catchError`. Here's how it works:

1. It spots an error.
2. It catches the error.
3. You decide whether to process the error or just throw it out altogether.

To help you visualize this process, imagine working on an assembly line of chocolate-coated fruit candies. Your job is to make sure everything on the belt is candy. If it’s not candy, you should dip it in chocolate ("chocolatize" it) to turn it into candy. 

You’re operating your conveyor belt inspecting each item. Everything is fine until you spot a 🍓fruit🍓 that should be dipped into chocolate. Let's turn this into code.

In my example code below, `const mapAndContinueOnError` maps each value from an Observable. On an error,  `catchError` catches the error and returns an Observable of `chocolatize fruit`. I declare `const candies` for the values of `Observable<string>`. Then I have a check to throw an error when I see `fruit 1`, piping to `mapAndContinueOnError`.

```

import { throwError, of, from, iif, pipe } from 'rxjs';
import { catchError, map, flatMap } from 'rxjs/operators';

const mapAndContinueOnError = pipe(
  map((v) => v),
  catchError((err) => {
    console.log('Fruit has been chocolatized');
    //Return the chocolatize fruit
    return of('chocolatize fruit');
  })
);

//Release the candy!
const candies: Observable = from([
  'candy 1',
  'candy 2',
  'fruit 1',
  'candy 3',
  'candy 4',
]).pipe(
  flatMap((value) =>
    iif(
      () => value != 'fruit 1',
      of(value),
      throwError(new Error('Fruits need to be dipped in chocolate!'))
    ).pipe(mapAndContinueOnError)
  )
);

candies.subscribe((value) => console.log(value));
/**
 * Output:
 * 
 * candy 1
 * candy 2
 * Fruit has been chocolatized
 * chocolatize fruit
 * candy 3
 * candy 4
 */
```

## retry

Next up is `retry`, which does exactly what it sounds like! Whenever there’s an error it will `retry` however many times you declare.

The code has `const candies` with the value `['candy 1', 'candy 2', 'fruit']` and I use `mergeMap` to go through each value within the object to find `fruit` and throw an error which will then be rerun twice to produced the output.

```
const candies: Observable = from(['candy 1', 'candy 2', 'fruit']).pipe(
  mergeMap(val => {
    if (val === 'fruit') {
      return throwError('Error!');
    }
    return of(val);
  }),
  // Get it to repeat twice
  retry(2)
);

candies.subscribe((value) => console.log(value), retry(2));

/**
 * Output: 
 * candy 1
 * candy 2
 * candy 1
 * candy 2
 * candy 1
 * candy 2
 */
```

## retryWhen

`retryWhen` is similar to `retry`but with a specified condition you define. Say you have a backend service you're making requests to and there's a `5xx` error type you want to supply an arbitrary error message for. For instance, you’d be able to check the status code for errors starting with a `5`. 

**Example:**

I have `fakeBackend` that I get data from. I want to retry getting the data if the status code of the error starts with `5` meaning any server error. I will keep retrying the code until I don’t get an error or until I don’t get an error code starting with `5`.

```
const resp$ = fakeBackend.getData().pipe(
  retryWhen(errors =>
    errors.pipe(
      delay(1000),
      tap(err => {
        if (err.statusCode.startsWith('5')) {
          throw err;
        }

        console.log('Retrying...');
      })
    )
  )
);

resp$.subscribe({
  next: console.log
});
```

## Conclusion

It's important to handle errors gracefully as a best practice. You want to enable the user to have an uninterrupted experience using your application. Within the Javascript ecosystem, RxJS has many useful tools to help you handle errors.

If you want to learn more about RxJS, be sure to check out our free [Bitovi Academy course](https://www.bitovi.com/academy/learn-rxjs.html?hsLang=en-us)!

[![Tag for rxjs](https://www.bitovi.com/hubfs/limbo/icons/tag.svg) rxjs ](https://www.bitovi.com/blog/topic/rxjs)[![Tag for best practices](https://www.bitovi.com/hubfs/limbo/icons/tag.svg) best practices ](https://www.bitovi.com/blog/topic/best-practices)

 Previous Post

![How to Break Down Epics into User Stories](https://www.bitovi.com/hs-fs/hubfs/How%20to%20Break%20Down%20Epics%20into%20User%20Stories.png?height=117&name=How%20to%20Break%20Down%20Epics%20into%20User%20Stories.png) [ How to Break Down Epics into User Stories ](https://www.bitovi.com/blog/how-to-break-down-epics-into-user-stories)

  

 Next Post

![](https://www.bitovi.com/hs-fs/hubfs/esther-jiao-ADv0GiMBlmI-unsplash.jpg?height=117&name=esther-jiao-ADv0GiMBlmI-unsplash.jpg) [ How to Solve Common Value Boxing Issues in ngrx-forms ](https://www.bitovi.com/blog/how-to-solve-common-value-boxing-issues-in-ngrx-forms)

```json
{
  "@context" : "http://schema.org",
  "@type" : "Organization",
  "address" : {
    "@type" : "PostalAddress",
    "addressCountry" : "United States",
    "addressLocality" : "Libertyville",
    "addressRegion" : "IL",
    "postalCode" : "60048",
    "streetAddress" : "1134 Pine Tree Lane "
  },
  "alternateName" : "Bitovi",
  "areaServed" : {
    "@type" : "GeoCircle",
    "geoMidpoint" : {
      "@type" : "GeoCoordinates",
      "latitude" : "41.8781",
      "longitude" : "87.6298"
    },
    "geoRadius" : "5000 km"
  },
  "description" : "Bitovi is a UX, UI design and front-end JavaScript development consulting company",
  "email" : "contact@bitovi.com",
  "image" : "https://www.bitovi.com/hubfs/bitovi-logo-x2.png",
  "logo" : "https://www.bitovi.com/hubfs/bitovi-logo-23-1.svg",
  "mainEntityOfPage" : {
    "@id" : "https://www.bitovi.com/blog/handling-errors-with-rxjs",
    "@type" : "WebPage",
    "description" : "Handling errors gracefully gives your users a better experience. Learn useful RxJS error handling operators: catch and catchError, retry, and retryWhen."
  },
  "naics" : "541511",
  "name" : "Bitovi Web App Consulting",
  "sameAs" : [ "https://www.facebook.com/BitoviLLC/", "https://twitter.com/bitovi", "https://www.linkedin.com/company/bitovi" ],
  "telephone" : "312-620-0386",
  "url" : "http://bitovi.com"
}
```

```json
{
  "@context" : "http://schema.org",
  "@type" : "BlogPosting",
  "author" : {
    "@type" : "Person",
    "name" : "Adrian Ferguson"
  },
  "dateModified" : "February 22, 2022, 3:26:29 PM",
  "datePublished" : "2022-02-22 15:26:29",
  "description" : "Handling errors gracefully gives your users a better experience. Learn useful RxJS error handling operators: catch and catchError, retry, and retryWhen.",
  "headline" : "Handling Errors with RxJS",
  "image" : {
    "@type" : "ImageObject",
    "url" : "https://www.bitovi.com/hubfs/Table%20with%20Sweet%20Brigadeiro%20-%20Its%20typical%20in%20Brazil.jpeg"
  },
  "publisher" : {
    "@type" : "Organization",
    "logo" : {
      "@type" : "ImageObject",
      "url" : "https://www.bitovi.com/hubfs/bitovi-logo-23-1.svg"
    },
    "name" : "Bitovi"
  }
}
```