Mikkel
Mikkel

Reputation: 196

Is it impossible to catch errors inside a subscription?

I am using Angular 7 where I am trying to catch an error thrown because a value returned by the external api had null values where I expected values.

I can't seem to figure out what I am supposed to do in this scenario.

I have a service that call the api.

getObjectValue(param: paramtype): Observable<ObjectValue> {
    return this.http.get<objectwithvalues>(environment.baseapiurl + '/api/object/value/'+ param);
  }

In the consuming component I subscribe like I always would

testfunction() {
   this.service.getObjectValue().Subscribe(v => {
    *DO STUFF*
    *Error happens* v['o'] // oh no v is null
   },
    error=>{
     console.log('error') 
     this.snackbar.open('this went wrong' + error); 
    }
  );
}

That is the basic case. Doing this does not trigger 'error=>{}' Angular simply spits out an error message.

So I tried try/catch within the subscribe callback scope. Did not catch.

I am currently trying to change the service code to the following

getObjectValue(param: paramclass): Observable<ObjectValue> {
    return this.http.get<EventWifi>(
      environment.baseapiurl + '/api/object/value/'+ param).pipe(map(v=> {
   if(v === null){
     return throwError('v is null');  
   } 
  }),
   catchError(err => this.errorTest(err))
);
  }

this.errorTest(err: any): Observable<any> {
 return throwError(err);

}

While doing the same in the subscriber, but the error is never caught by the subscribing error function so I am unable to handle the error appropriately.

With the latest shown service function no error is thrown at all.

I have tried so many small differences in configuration I can hardly remember at this point, so there must be a basic thing I am messing up.

I have looked at so many examples but none of them catch and work in my case.

Upvotes: 6

Views: 11092

Answers (3)

Ashique Razak
Ashique Razak

Reputation: 685

The latest Angular version requires error to be handled inside the subscribe the following way

this.http.get(url).subscribe(
 {
   next: (data) => 
   {
     //do something
   },
   error: (error) =>
   {
     //handle error
   }
 }
);

Upvotes: 1

Ashish Ranjan
Ashish Ranjan

Reputation: 12950

Your error is that you are returning an Observable of an Observable while doing a throwError in map, use mergeMap instead.

return this.http.get<EventWifi>(url).pipe(mergeMap(v=> {
   if(v === null){
     return throwError('v is null');  
   } else {
        return of(v)
   } 
})

Under subscribe, an Observable is not an error.

https://stackblitz.com/edit/angular-uglwbm

Upvotes: 1

Poul Kruijt
Poul Kruijt

Reputation: 71891

The issue is that you are trying to handle the error inside your subscription function. This will never reach your error function, simple because it can't. You should throw the error from within a pipe. Preferably in the mergeMap:

getObjectValue(param: paramtype): Observable<ObjectValue> {
  return this.http.get(environment.baseapiurl + '/api/object/value/'+ param).pipe(
    mergeMap((v) => v == null ? throwError('v is null') : of(v)) 
  );
}

You can then do this:

testfunction() {
  this.service.getObjectValue().subscribe((v) => {
    // v will never be null
  },
  (error) => {
    console.log('error') 
    this.snackbar.open('this went wrong' + error); 
  });
}

If this is something that occurs a lot in your application, you can create a HttpInterceptor which does this for you. You can make it throw the http call with a certain error code and number if the return value is null.

Upvotes: 6

Related Questions