【问题标题】:Rxjs catchError not working when subscribe after pipe在管道后订阅时,Rxjs catchError 不起作用
【发布时间】:2020-01-20 01:49:00
【问题描述】:

我创建了一个 observable 来使用 API

可观察:-

    return this.http.post('/api/ApplicationUser/Login', loginDetails, httpOptions).pipe(
      map((result: any) => {
        localStorage.setItem('jwtToken', result.jwtToken);
        localStorage.setItem('refreshToken', result.refreshToken.value)
        localStorage.setItem('UserName', result.userName);
        return result;
      }),
      catchError((err: any) => {
        //this.userLogout()
        console.log('refresh error')
        return throwError(err);
      })
    );
  }

当我使用以下代码激活时,根据我的情况,上面的代码可以正常工作或抛出错误:-

    this.loginService.getNewRefreshToken().subscribe(
      (res => { console.log(res) }),
      (err => { 
        this.loginService.userLogout()
        console.log(err)
      }),
      () => { console.log('subscription completed')},
    );

但我的问题是,当我使用下面的代码激活它时,它的 catchError 不起作用但结果很好。 为什么 catchError 在以下情况下不起作用?

    return this.loginService.getNewRefreshToken().pipe(
      map((res: any) => {
        console.log(res);
      }),
      catchError((err: any) => {
        console.log(err);
        return throwError(err);
      })
    ).subscribe(
      (res => {
      console.log(res)
    }),
      (err => {
        console.log(err)
      })
      )

【问题讨论】:

  • catchError 语句中的哪一个没有触发?
  • catchErrorif (!this.tokenRefreshing) {} 这个块内
  • 你的代码看起来不错
  • 您的代码似乎在 StackBlitz 上运行良好。我在这里看到的唯一问题是当您在loginService.getNewRefreshToken 中使用map 时,您没有返回任何内容,因此您的数据将以undefined 的形式出现。您还应该使用tap 而不是map,因为您只想执行副作用而不实际操作数据。正如您在答案中的一个 cmets 中提到的,@ 987654332@ 问题必须与拦截器有关。另一方面,你为什么要在你的组件中再次捕获错误?

标签: angular rxjs angular7


【解决方案1】:

您的 getNewRefreshToken 函数会吃掉异常,因此它不会传播到上游侦听器。

试试throwError

 getNewRefreshToken(): Observable<any> {
   var loginDetails: LoginDetails = {
   email: localStorage.getItem('UserName'),
   grantType: 'refreshToken',
   password: '',
   refreshToken: localStorage.getItem('refreshToken')
  }

const httpOptions = {
  headers: new HttpHeaders({
    'Content-Type': 'application/json',
    'Authorization': 'my-auth-token'
  }),
 };

return this.http.post('/api/ApplicationUser/Login', loginDetails, httpOptions).pipe(
  map((result: LoginResponse) => {
    localStorage.setItem('jwtToken', result.jwtToken);
    localStorage.setItem('refreshToken', result.refreshToken.value)
    localStorage.setItem('UserName', result.userName);
    return result;
  }),
  catchError((err: any) => {
    this.userLogout()
    console.log('refresh error')
    return throwError(err);  //<-- insert this 
  })
);
}

Sample 在控制台查看结果。

【讨论】:

  • 我试过了,但是代码没有进入 catchError 块本身
  • 不检查那个块执行我添加了那个。但它不工作
  • 如果refresh error没有被打印出来,这意味着你的POST调用正在返回正确的响应。检查您的 webapi 是否确实返回了预期的返回码。
  • 我可以看到发布请求为 401
  • 尝试在单击按钮时使用catchError 调用发布请求方法,并查看catchError 块是否按预期工作。我怀疑这里有什么可疑之处。
猜你喜欢
  • 2018-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-28
  • 2018-09-16
  • 1970-01-01
相关资源
最近更新 更多