【问题标题】:RxJS- Conditionally using RetryWhen operatorRxJS- 有条件地使用 RetryWhen 运算符
【发布时间】:2021-11-25 19:47:45
【问题描述】:

我想为基于 Observable 的 Firebase 请求设计一个可扩展的错误处理策略。为此,我尝试为每种类型的错误创建一个自定义的 RxJS 运算符(例如unauthenticatedinternal,你可以命名它)。操作符会在请求后堆叠如下:

FirebaseRequestObservable.pipe(
...
handleUnauthenticatedError(),
handleInternalError(),
handleYouNameItError(),
...
)

如果我的错误处理运算符仅由 catchError 运算符构成,这可以正常工作,在这种情况下,它的内部结构可以简单地是:

source.pipe(
catchError((err) => {
  if (err !== errorThisOperatorShouldHandle) {
   throw err 
   } 
  handleError
 }
))

如果错误不应该由该操作员处理,则错误会传递到下一个自定义操作员。

当我对某个错误的错误处理逻辑涉及使用retryWhen 时,问题就出现了。我不知道如何让操作员有条件地使用retryWhen,如果它是正确的错误,如果不是,则将错误重新抛出给下一个操作员。

对于这个问题的任何帮助或对可扩展错误处理系统的不同策略的建议将不胜感激。谢谢!

【问题讨论】:

    标签: rxjs rxjs-pipeable-operators


    【解决方案1】:

    它们非常相似。 以下是我如何实现这两个:

    处理特定错误。

    function handleYouNameItError<T>(): MonoTypeOperatorFunction<T> {
    
      return catchError(err => {
        if(err !== youNameItError){
          return throwError(() => err);
        }else{
          // handleError
          return EMPTY;
        }
      });
    
    }
    

    重试特定错误。

    function retryYouNameItAnotherError<T>(): MonoTypeOperatorFunction<T> {
    
      return retryWhen(err$ => err$.pipe(
        tap(err => {
          if(err !== youNameItAnotherError){
            throw err;
          }
        }),
        // Delay 1s between retries
        delay(1000),
        // Only retry 5 times
        take(5),
        // After 5 retries, throw a new error
        concatWith(throwError(() => 
          new YouNameItAnotherErrorFailedAfterRetries()
        ))
      ));
    
    }
    

    将它们用作运算符:)

    FirebaseRequestObservable.pipe(
      ...
      handleYouNameItError(),
      retryYouNameItAnotherError()
      ...
    );
    

    【讨论】:

    • 非常感谢您的回答。这正是我所需要的。有趣的是,我没想过在 retryWhen 中简单地抛出错误!
    猜你喜欢
    • 2021-05-25
    • 2017-07-31
    • 1970-01-01
    • 2022-08-21
    • 2019-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多