1

After an error-response from the server my app does not send any further requests.

I'm sending a request with:

getMachineRules(rules: Array<string>): Observable<RulesResults> {
    return this.http.post<RulesResults>('/rules', { nodes: rules })
      .pipe(
        catchError(this.handleError)
      );
  }

My errorHandler:

  handleError(error) {
    if (error.error instanceof ErrorEvent) {
      console.error('An error occurred:', error.error.message);
    } else {
      console.error(
        `Backend returned code ${error.status}, ` +
        `body was: ${JSON.stringify(error.error)}`);
    }
    return throwError('Something bad happened; please try again later.');
  }

And my pipeline looks like this:

  ngAfterViewInit() {
    this.rulesChanged
      .pipe(
        startWith({}),
        switchMap(() => {
          this.isLoadingResults = true;
          return this.settings.getMachineRules(this.currentRules);
        }),
        map(data => {
          this.isLoadingResults = false;
          this.resultsLength = data.inputs?.length || 0;
          return data;
        }),
        catchError(e => {
          console.log("Error caught");
          this.isLoadingResults = false;
          this.resultsLength = 0;
          return observableOf({ inputs: [] } as RulesResults);
        })
      ).subscribe(
        data => { return this.updateRules(data); },
      );
  }

I can see the "Error caught" message in the console and the method updateRules() seems to work properly even in the error case.

However after a 404-Error-Response the ngAfterViewInit() method is not called anymore. The UI steel reacts on interactions.

3
  • what do you mean by "the ngAfterViewInit() method is not called anymore"? like you refresh the browser and it is not called? Commented Dec 14, 2020 at 17:09
  • no, i click a button which should trigger ngAfterViewInit(), but the method is not executed Commented Dec 14, 2020 at 17:18
  • 1
    the Observable's stream is "dead" after going thru the process the first time. calling the ngAfterViewInit will not re-trigger the this.rulesChanged's Observable stream to start again, i think (though i do not know what this.rulesChanged looks like). Commented Dec 14, 2020 at 20:15

1 Answer 1

3

Once an Obsevable is failed there is nothing you could do to make it active again, catchError is used to handle errors by returning a new observable or throwing an error. observableOf({ inputs: [] } as RulesResults) is served as substitute in case the main stream fails, meaning your main Observable will never emit again.

Consider using retry at the end of your pipeline, or optionally have your catchError return the source Observable itself, as demonstrated below:

catchError((error, source) => {
 ....
  return source;
})

Alternately put the catchError operator inside a switchMap so that only the inner stream will fail while the the outer (main) stream will remain active, as below:

ngAfterViewInit() {
  this.rulesChanged
    .pipe(
      startWith({}),
      switchMap(() => {
        this.isLoadingResults = true;
        return this.settings.getMachineRules(this.currentRules).pipe(
          map(data => {
            this.isLoadingResults = false;
            this.resultsLength = data.inputs?.length || 0;
            return data;
          }),
          catchError(e => {
            console.log("Error caught");
            this.isLoadingResults = false;
            this.resultsLength = 0;
            return observableOf({ inputs: [] } as RulesResults);
          })
        )
      })
    ).subscribe(
      data => { return this.updateRules(data); },
    );
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much for the solution and the explanation! The 2nd solution worked! The 1st one turns the pipe into an endless loop.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.