Angular 7 - 如何在某些响应状态代码上重试 http 请求?

Posted

技术标签:

【中文标题】Angular 7 - 如何在某些响应状态代码上重试 http 请求?【英文标题】:Angular 7 - How to retry an http request on certain response status codes? 【发布时间】:2019-09-08 23:17:14 【问题描述】:

我正在尝试从 Angular 拦截器捕获 http 请求的错误,并将 401 处理为注销,同时重试 503 和 504 响应 n 次。

这是我的 http 拦截器:

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> 

    return next.handle(req).pipe(
      catchError(error => 
        if (error.status === 401) 
          this.authenticationService.logout();
          this.router.navigate(['login']);
        

        return throwError(error);
      ),
      retryWhen(errors => errors
        .pipe(
          concatMap((error, count) => 
            if (count < 2 && (error.status == 503 || error.status == 504)) 
              return of(error.status);
            

            return throwError(error);
          ),
          delay(500)
        )
      )
    );
  

我 100% 确定我编写这段代码时可以正常工作,因为我测试了多次,但现在它给了我:

UnsubscriptionErrorImpl 
message: "1 errors occurred during unsubscription:↵1) TypeError: Cannot read property 'apply' of null", name: "UnsubscriptionError", errors: Array(1)

errors: Array(1)
   0: TypeError: Cannot read property 'apply' of null at RetryWhenSubscriber._zoneUnsubscribe (http://localhost:4200/polyfills.js:8506:44) at RetryWhenSubscriber.push../node_modules/rxjs/_esm5/internal/Subscription.js.Subscription.unsubscribe (http://localhost:4200/polyfills.js:3739:30) at RetryWhenSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.unsubscribe (http://localhost:4200/polyfills.js:3524:38) at RetryWhenSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber._unsubscribeAndRecycle (http://localhost:4200/polyfills.js:3541:14) at RetryWhenSubscriber.push../node_modules/rxjs/_esm5/internal/operators/retryWhen.js.RetryWhenSubscriber.notifyNext (http://localhost:4200/vendor.js:155632:14) at InnerSubscriber.push../node_modules/rxjs/_esm5/internal/InnerSubscriber.js.InnerSubscriber._next (http://localhost:4200/polyfills.js:2717:21) at InnerSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next (http://localhost:4200/polyfills.js:3504:18) at InnerSubscriber.rxjs.Subscriber.next (http://localhost:4200/polyfills.js:8537:29) at Notification.push../node_modules/rxjs/_esm5/internal/Notification.js.Notification.observe (http://localhost:4200/polyfills.js:2769:50) at AsyncAction.push../node_modules/rxjs/_esm5/internal/operators/delay.js.DelaySubscriber.dispatch (http://localhost:4200/vendor.js:153337:40)
length: 1
__proto__: Array(0)
message: "1 errors occurred during unsubscription:↵1) TypeError: Cannot read property 'apply' of null"
name: "UnsubscriptionError"

上次工作时,我使用的是 Angular 6。现在我使用的是 Angular 7。 我已经尝试了不同的 rxjs 版本无济于事。

如何解决这个问题并实现一个简单的重试逻辑?

编辑:

我刚刚注意到,如果我从 poliyfills.ts 文件中删除 import 'zone.js/dist/zone-patch-rxjs';,那么它可以工作,但其他事情会停止工作。

【问题讨论】:

我在我的文章中回顾了一个类似的任务:medium.com/@alexanderposhtaruk/… 【参考方案1】:

401 需要关闭流以避免进一步的逻辑。

        if (error.status === 401) 
          this.authenticationService.logout();
          this.router.navigate(['login']);
          return EMPTY; // <- add this
        

【讨论】:

以上是关于Angular 7 - 如何在某些响应状态代码上重试 http 请求?的主要内容,如果未能解决你的问题,请参考以下文章

使用查询字符串在新服务器上重定向的角度路由

Angular 5:预检响应具有无效的 HTTP 状态代码 403

Angular $http:预检响应具有无效的 HTTP 状态代码 403

在 Laravel POST 请求上重定向 302

预检响应具有无效的 HTTP 状态代码 403 + angular 2 + Java Spring boot

Angular 2 - 预检响应具有无效的 HTTP 状态代码 401