【问题标题】:How to properly handle errors using retryWhen in rxjs如何在 rxjs 中使用 retryWhen 正确处理错误
【发布时间】:2020-04-03 23:38:54
【问题描述】:

当出现 502 bad gateway 错误时,我需要重试特定 API 调用大约 3 次。重试可能会稍微增加延迟。这是组件中的代码。

some.component.ts

someMethod() {
    let attempt = 0;
    this.someService.AppendSubject(this.subject)
    .pipe(retryWhen(errors => errors.pipe(
        tap(error => this.retryApi(error, ++attempt, 'Server busy. Retrying request', this.subject))
    )))
    .subscribe(response => {
        //do something with response
    });
}

retryApi(error: any, attempt: number, retryMessage: string, data?: any) {
    delay(this.duration*attempt)
    //show toast with retryMessage
    if (attempt > this.retryLimit) {
        //show some message
        if (data)
            this.notifyFailure(data);
        throw error;
    }
}

notifyFailure(data: any) {
    this.someService.notifyFailure(data);
}

some.service.ts

public AppendSubject(data: any) {
    return this.http.post<any>(`{env.api}/appendsubject/`, data);
}    

public notifyFailure(data: any) {
    return this.http.post<any>(`{env.api}/notifyfailure/`, data);
}
  • 在服务器上根本没有命中 notifyFailure 端点 一边。

这是由于我在重试中如何做/不做错误捕获吗?如何正确捕获上述代码中的错误,并且不阻碍或终止进一步的 notifyFailure 调用?

注意:我目前没有在拦截器中执行此操作,因为此时这仅适用于特定的 API。我正在组件中编写重试处理程序,而不是在 some.service.ts 级别,因为我不知道如何做到这一点,同时在组件中显示适当的 toast 和弹出窗口。

【问题讨论】:

    标签: angular rxjs retrywhen


    【解决方案1】:

    美好的一天! 我更喜欢使用这种方法:

    您的服务:

    getSomething(retryCount: number = 0, retryInterval: number = 1000) {
        return this.http.get(this.getSomethingUrl).pipe(
          retryWhen((error: Observable<any>) => error.pipe(
            delay(retryInterval),
            take(retryCount)
          ))
        );
      }
    

    在组件中:

    this.service.getSomething(3, 2000).subscribe(response => {
      // Handle success
    }, error => {
      // Here you can send a request to your BE (triggers only after 3 failed requests in this case), to notify about the occurred error
      // Also you can do it in your pipe using `catchError` rxjs operator
    });
    

    【讨论】:

      【解决方案2】:

      根据 AlexanderFSP 的回答,我修改了我的代码以通过这种方式捕获错误。

      .pipe(retryWhen(errors => errors.pipe(
          tap(error => this.retryApi(error, ++attempt, 'Server busy. Retrying request', this.subject)),
          catchError(() => {
              this.notifyFailure(data);
              return EMPTY;
          })
      )))
      .subscribe(response => {
          //do something with response
      });
      

      它现在正在工作。

      【讨论】:

        猜你喜欢
        • 2023-03-29
        • 1970-01-01
        • 1970-01-01
        • 2021-12-16
        • 1970-01-01
        • 1970-01-01
        • 2017-12-05
        • 2019-05-25
        • 1970-01-01
        相关资源
        最近更新 更多