You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在特定场景下使用retryWhen并获取错误状态码?

解决方案

你的核心问题在于服务端retryWhen的实现里,最终抛出的错误对象没有正确传递到组件的错误回调中,同时重试逻辑的终止条件处理存在偏差。我们可以通过调整retryWhen的逻辑,确保完整的错误信息能传递到组件,同时保留重试和差异化错误处理的能力。

第一步:修正服务中的重试逻辑

原来的concat(Observable.throw(error))引用的是retryWhen函数的外层error参数,这会导致最终抛出的错误不是最后一次请求失败的真实错误对象。我们可以用scan操作符跟踪重试次数,当次数达到上限或遇到非501错误时,抛出原始错误。

修改后的服务代码:

return this.prepaidPaymentProxyService.performAirtimePrepaidPayment(request)
  .retryWhen(errors => {
    let retryCount = 0;
    return errors.pipe(
      scan((_, error) => {
        retryCount++;
        // 仅当状态码为501且重试次数未达上限时,继续重试
        if (retryCount <= 5 && error.header.statuscode === '501') {
          console.log(`Retry attempt ${retryCount}`);
          return error;
        }
        // 超过次数或非501错误,抛出原始错误
        throw error;
      }, null),
      delay(1000) // 每次重试间隔1秒
    );
  });

第二步:组件中正确处理错误对象

现在完整的错误对象能传递到组件的error回调里了,你可以直接提取statuscode,执行差异化处理:

buyPrepaidMobile(data) {
  this.loader.startLoading();
  this.buyPrepaidMobileService.onBuyPrepaidMobile(data).subscribe(
    response => {
      this.buyPrepaidMobileService.handlebuyPrepaidMobileSuccess(response);
      this.activeStep = 3;
      this.progressIndicator.setStep(3);
      this.loader.stopLoading();
    },
    error => {
      this.loader.stopLoading();
      const statusCode = error.header.statuscode;
      
      if (statusCode === '501') {
        console.log('Retried 5 times, ended with failure');
      }
      // 传入状态码调用统一错误处理函数
      this.buyPrepaidMobileService.handlebuyPrepaidMobileError(statusCode);
      
      this.activeStep = 3;
      this.progressIndicator.setStep(3);
    }
  );
}

这里调整了loader.stopLoading()的顺序,避免重复启动加载的问题,同时明确区分了501重试失败的日志和通用错误处理逻辑。

原实现的问题根源

原来的take(5).concat(Observable.throw(error))中,error是retryWhen函数的外层参数,并非每次错误流中的具体错误对象,这导致组件拿到的错误不是最后一次请求的真实错误,自然无法正确提取statuscode。而scan的方式可以在每次错误发生时判断是否重试,终止时抛出原始错误,保证了错误信息的完整性。

内容的提问来源于stack exchange,提问作者Vinod Bhavnani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:32:38