RxJS: the art of triggering and handling errors

This is more of a syntax question rather than a bug I'm facing.

The process is straightforward:

  • Send an HTTP request that returns a boolean value
  • If the boolean is true, proceed
  • If the boolean is false, log a warning and stop the flow.

To handle this, my current code looks like this:

Basic Setup

private _getBoolean() { return this.http.get(...); }
private _getData() { return this.http.get(...); }

Current Implementation

public getData() {
  return this._getBoolean().pipe(
    filter(bool => {
      if(!bool) {
        console.warn('Incorrect server response, stream stopped');
        return false;
      }
      return true;
    }),
    switchMap(bool => this._getData())
  );
}

However, I feel like there might be a more natural and optimized way to do this.

I was wondering if there is a simpler syntax, something like this:

public getData() {
  return this._getBoolean().pipe(
    throwError(bool => bool ? new Error('Incorrect server response, stream stopped') : null),
    catchError(err => console.warn(err)),
    switchMap(bool => this._getData())
  );
}

Is there an approach similar to this, or am I using the correct syntax?

Answer №1

When dealing with an observable that emits values from 1 to 4, it's important to consider how errors are handled. For example, if an error occurs when the value is 3, you have the option to catch that error using the catchError operator or within the subscribe method. The decision of where to handle the error depends on the specific use case and whether it should be allowed to propagate up to the subscriber or dealt with earlier in the pipeline.

of(1, 2, 3, 4).pipe(
  // Throw error when value is 3
  tap(value => { if(value === 3) throw new Error('Oops!') }),
  catchError(err => {
    console.log('Catch error in operator', err);

    // You can choose to rethrow the same error or a new one
    // return throwError(err);

    // Alternatively, handle the error and return a new observable
    return of(3)
  })
).subscribe(
  value => console.log(value),
  // If `catchError` returns a new observable, the error handler 
  // function here will not be triggered
  err => console.log('Catch error within subscribe', err),
  () => console.log('Done!')
)

It's worth noting that in this scenario, even though the error is managed, the observable still completes and the value 4 is never emitted. To keep the observable running when an error occurs, refer to this StackOverflow solution.

Answer №2

rather than:

public fetchData() {
  return this._getStatusCode().pipe(
    throwError(status => status ? new Error('Incorrect server response, stream halted') : null),
    catchError(error => console.warn(error)),
    switchMap(status => this._fetchData())
  );
}

how about trying this approach instead:

public fetchData() {
  return this._getStatusCode().pipe(
    tap(response => !response && throwError('Incorrect server response, stream halted')),
    switchMap(status => this._fetchData()),
    catchError(error => console.warn(error))
  );
}

Answer №3

It seems like there may be a misunderstanding in your problem, but you could try replacing

    console.warn('Wrong server answer, stream stopped');
    return false;

With

   Observable.throw('Some error cause')

Then catch it with the closest catch block in your stream, which allows you to: - Stop the stream if you re-throw an error - Restart it if you return the input observable - Return a completely new observable

public getData() {
  return this._getBoolean().pipe(
    filter(bool => {
      if(!bool) {
        console.warn('Wrong server answer, stream stopped');
        //return false;
        Observable.throw('I got false where I expected true')
      }
      return true;
    }),
    switchMap(bool => this._getData())
  );
}

After that:

getData()
.any()
.operator()
.you()
.wish()
.catch(e => {
  /* The stream will be terminated on a thrown error here */
})

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Angular template variables in VS Code now have the ability to automatically update their names when renamed

Here is a snippet from the controller: /* Local copies of Enumerators to use on template */ MeasurementOriginEnum: typeof MeasurementOriginEnum = MeasurementOriginEnum; And here is how it is used in the template: <button *ngIf="element.getMeasure ...

Steps for aligning the upper rectangular text in the center of the larger rectangular border

https://i.stack.imgur.com/7yr5V.png I was aware of a particular element in html that had text positioned in the upper left corner, but my knowledge didn't go beyond that. Should I be adjusting the translation on both the X and Y axes based on the par ...

Ways to transfer information from HTML form components to the Angular class

I am currently working with angular 9 and I have a requirement to connect data entered in HTML forms to the corresponding fields in my Angular class. Below is the structure of my Angular class: export interface MyData { field1: string, textArea1 ...

Utilize ngrx/store to capture events from various components within an Angular application

Is there a way to utilize ngrx store in Angular to capture events from a grandchild component without relying on a service, Behavior Subject, or @Output? ...

Initiate the deployment of the updated npm package

After I installed the npm package ngx-cookie-service, I made changes to the code in the node_module > ngx-cookie-service folder. While these changes worked perfectly on my local host, they did not work when I deployed my Angular app to Azure. What step ...

What sets apart angular-cli from @angular/cli in the npm ecosystem?

Two angular cli packages can be found on npm: angular-cli currently at version 1.0.0-beta.28.3 @angular/cli currently at version 1.0.0-beta.31 What sets these two packages apart, and which one is recommended for a new project? The information provided ...

Encountering a style-loader error while trying to upgrade to Angular 15 using @angular-builders/custom-webpack

Check out my demo repository at the following link: https://github.com/OrShalmayev/style-loader-error After upgrading my Angular project from version 12 to 15, I encountered an issue with my angular.json file configuration: "architect": { &q ...

A guide to sending epoch time data to a backend API using the owl-date-module in Angular

I have integrated the owl-date-time module into my application to collect date-time parameters in two separate fields. However, I am encountering an issue where the value is being returned in a list format with an extra null value in the payload. Additiona ...

Having trouble retrieving a specific key from the state object in Redux using TypeScript

I have incorporated TypeScript into my Ionic project, using React hooks. I recently added an errorReducer to handle any errors that may arise from the server. Below is a snippet of my code: Action import { ERROR_OCCURRED } from "./types"; ...

What is the best way to adjust the size of an HTML5 SVG circle with a button click event?

If you click the button, the text size will increase or decrease. <div class="buttons"> <button (click)="fSize = fSize + 1">+</button> <button (click)="fSize = fSize - 1">-</button> </div> <br> <div [ ...

Restricting types does not appear to be effective when it comes to properties that are related

I am working with a specific type that looks like this: type Props = { type: 'foo'; value: string; } | { type: 'baz'; value: number; }; However, when using a switch statement with the type property in TypeScript, the program in ...

Is it necessary for a TypeScript Library's repository to include the JavaScript version?

Is it necessary to include a JavaScript version of the library along with the Typescript repository for consumers? Or is it best to let consumers handle the compilation process themselves? Or should I consider another approach altogether? ...

What is the alternative to using toPromise() when utilizing await with an Observable?

This website mentions that "toPromise is now deprecated! (RxJS 5.5+)", however, I have been utilizing it recently with AngularFire2 (specifically when only one result is needed) in the following manner: const bar = await this.afs.doc(`documentPath`).value ...

What's the trick to inserting a "dot" beneath a DatePicker?

Could someone assist me in adding a small "dot" below certain dates on MUIX DatePicker, similar to the example shown here? Thank you. ...

Uploading files in Angular application

I'm facing some minor issues with file uploads for the first time. My project consists of an Angular 7 app and a NodeJS (express) backend. I have successfully uploaded images through the Angular page and stored them with the correct format in NodeJS. ...

The command 'ng' is not valid in this context, please make sure it is being used correctly within the program or batch file

After attempting to install angular-cli with npm install -g, I hit a roadblock. Next, I attempted to add it to the PATH under Environment Variables but encountered no success. ...

Exploring project references in TypeScript 3 with distinct `outDir` configurations

I am eager to utilize the project references functionality in TypeScript 3.1. Initially, my project's directory structure post-compilation appears as follows: . ├── A │ ├── a.ts │ ├── dist │ │ ├── A │ │ ...

I am currently unable to retrieve any results for my fullcalendar tooltip

I am currently working on setting tooltips for events using Primeng's fullcalendar. Despite initializing the tooltip in the web console, I am unable to see it when hovering over an event. My development environment includes Typescript, Primeng 7.0.5, ...

Is the ngrx adapter compatible with composite primary keys?

I'm working on implementing a composite primary key for an entity. Is there a way to successfully use a composite primary key in this case? Here is my goal: // I want my entity, DailyEvent, to be uniquely identified by [year, month, dayofmonth] expor ...

The supplied parameters do not correspond with any valid call target signature for the HTTP delete operation

I've been attempting to utilize the http delete method in Angular 2, but I keep encountering a typescript error: Supplied parameters do not match any signature of call target.. Below is the code I am using: let headers= new Headers(); ...