是否不可能在订阅中捕获错误?

时间:2019-03-28 14:41:15

标签: angular error-handling rxjs try-catch observable

我正在使用Angular 7,试图捕获引发的错误,因为外部api返回的值在我期望的值处为空值。

在这种情况下,我似乎无法弄清楚应该做什么。

我有一个调用api的服务。

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

在消费组件中,我一如既往地

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); 
    }
  );
}

这是基本情况。 这样做不会触发'error => {}' Angular只会吐出一条错误消息。

所以我尝试在订阅回调范围内尝试/捕获。没有抓住。

我目前正在尝试将服务代码更改为以下

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);

}

虽然在订阅服务器中执行相同的操作,但是订阅的错误功能从未捕获到该错误,因此我无法适当地处理该错误。

使用最新显示的服务功能,根本不会引发任何错误。

我已经尝试过配置上的许多细微差别,但现在我几乎不记得了,因此我必须弄清一个基本问题。

我看了很多例子,但在我的案例中没有一个能抓住并起作用。

2 个答案:

答案 0 :(得分:1)

问题是您正在尝试处理订阅函数内部的错误。这将永远不会达到您的错误功能,因为它无法实现。您应该从管道内抛出错误。最好在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)) 
  );
}

然后您可以执行以下操作:

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

如果这在您的应用程序中经常发生,则可以创建一个HttpInterceptor来为您执行此操作。如果返回值为空,则可以使其带有特定的错误代码和数字来引发http调用。

答案 1 :(得分:1)

您的错误是,您在throwError中执行map时返回了一个Observable对象,请改用mergeMap

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

在订阅下,可观察对象不是错误。

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