Angular http request observable error does not catch error?

10,484

Angular 6 uses RxJS 6, which comes with a number of changes. Assuming that's what you're using, this is what I would use:

Here's what I would use:

this.http.get(this.GRAPH_ROOT_URL + this.APP_ID, { headers })
    .pipe(catchError(err => {
      this.alert.error('There was an error getting data');
      return throwError(err);
    })).subscribe(data => this.notification.done(data));

So you use pipe to call catchError, which does handle the server errors correctly.

To use catchError, you need to import it first, like this:

import { catchError } from 'rxjs/operators';
Share:
10,484
SebastianG
Author by

SebastianG

Updated on June 06, 2022

Comments

  • SebastianG
    SebastianG almost 2 years

    Angular 6 using HttpClient. No interceptors implemented for now.

    I have an admin service where I'm doing a http call to MSGraph. In this case I'm getting an error 400 bad request which I'm sending to the notification handler.

    I've slided in that console.log to make sure that the error block is firing at all and another cnosole.log to see if the 'data' getting back from the server is an error.

    None of the console.logs fire yet the global error handler still displays the 400 bad request response in the console.

    I'd like to be able to use this response and display a user-friendly message.

    Code:

    this.http.get(this.GRAPH_ROOT_URL + this.APP_ID, { headers }).subscribe(data => {
      this.notification.done(data);
      console.log(data);
    }), error => {
      this.notification.error(`Error getting users from Microsoft GRAPH API. Reason: ${error}`)
      console.log("this is observable error", error);
    }
    
  • SebastianG
    SebastianG over 5 years
    Just tried this -- the only problem is the .pipe(catchError part -- the catchError is not defined/available from anywhere. I was able to import the throwError one from rxjs. I am indeed using RxJS6 -- not the latest version as that brings breaking changes to a lot of things that I'm using. But still RxJS6
  • SebastianG
    SebastianG over 5 years
    Thanks! This works exactly as intended. Kinda bummed I have to refactor 20+ http requests now, should've tested this a lot sooner! The only problem is now when I try to write the err object on the service it shows up as [object object]; I'm suspecting this is because of the order I'm doing things in and will tweak it a bit.
  • Cobus Kruger
    Cobus Kruger over 5 years
    @SebastianG While you're going to invest the time, go a step further and wrap HttpClient in a service of your own. It really makes this kind of thing simpler and gives you additional options. For example, my actual code also includes automatic retry for GET and visual notifications for success or failure.
  • SebastianG
    SebastianG over 5 years
    Is there any chance you have that example somewhere on github that I could take a look? I am wrapping everything in a service, it's just that I've got 4 services with observables in 2 apps that I'm working at the moment, almost all of them with a redux architecture. If I manage to do it right at the service level, it'll be an absolute breeze to then consume them in components.
  • Cobus Kruger
    Cobus Kruger over 5 years
    Sorry, no. My service basically has the same Get, Post, etc. functions, but adds pipe calls for catchError and retry (for Get only). It also calls the notification service, which seems similar to yours. The point is just that it gives you options and you can expand at will. I also have certain overloads that automatically place single objects in arrays and so on. You could probably do much of it with interceptors as well, but I would always wrap it.
  • SebastianG
    SebastianG over 5 years
    I understand, my only question is on the 'retry' logic. Is that purely in the case of a timeout or is there other benefits to retrying the GET request? Btw thanks a lot for your help so far, this has been very valuable to me.
  • Cobus Kruger
    Cobus Kruger over 5 years
    Aha. That's a simple .pipe(retry(2)) added just before my pipe for catchError. So it makes a maximum of three attempts and only then returns the error. retry is imported from the same module as catchError.
  • SebastianG
    SebastianG over 5 years
    hah! that would be very valuable, can't believe I haven't thought of that! Thanks for all man. Good luck!
  • Egor Pavlikhin
    Egor Pavlikhin about 4 years
    This doesn't work. BadRequest response still throws an exception in the browser but never hits the code.