首页 > 解决方案 > Angular中的HttpInterceptor不重试失败的请求

问题描述

这个问题很常见,stackoverflow 中提供了许多解决方案。但是,我无法让它发挥作用。“我失败的 http 请求无法重试”。

下面是拦截器的代码

import { Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor, HttpErrorResponse, HttpResponse } from 
'@angular/common/http';
import { Observable, throwError, BehaviorSubject } from 'rxjs';
import { catchError, filter, take, switchMap, map, retryWhen, delay } from 'rxjs/operators';
import { AuthenticateService } from '../services/authenticate.service';
import { ErrordialogService } from '../@hrms/services/errordialog.service';

@Injectable()
export class TokenInterceptor implements HttpInterceptor {

private isRefreshing = false;
private refreshTokenSubject: BehaviorSubject<any> = new BehaviorSubject<any>(null);

constructor(
  private _authService: AuthenticateService,
  private _errorDialogService: ErrordialogService
 ) { }

 intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
  let token: string = '';

/**
 * Pass the parsed token
 * If token present clone the request to add token to every requests
 */
if(this._authService.getTokens() !== null || this._authService.getTokens() !== undefined) {
    let extractedToken = JSON.parse(this._authService.getTokens());
    token = extractedToken;
}

if (token) {
  request = this.addToken(request, token);
}

/**
 * This is app specific
 * Need to pass @Apiversion as header
 */
if (!request.headers.has('Api-version')) {
    request = request.clone({ headers: request.headers.set('Api-version', '1') });
}

/**
 * Return the Observable
 */
return next.handle(request).pipe(
    map((event: HttpEvent<any>) => {
        if(event instanceof HttpResponse) {
            console.log('event---->>>', event);
        }
        return event;
    }),
    catchError((error: HttpErrorResponse) => {
        console.log(error);
        if(error.status === 401) {
            this.handle401Error(request, next);
        }
        else if(error.status === 500 || error.statusText === 'Unknown Error') {
          this.handleServerError(request, next, token);
        }
        else {
            return throwError(error);
        }
        return throwError(error)
    })
)

}

private addToken(request: HttpRequest<any>, token: string) {
 return request.clone({ setHeaders: { 'Authorization': `Bearer ${token}` } });
}

private handleServerError = (request, next, token) => {
 this._errorDialogService.showErrorDialog();
 console.log(request);
 return next.handle(request).pipe(retryWhen(errors => errors.pipe(delay(2000))))
}

private handle401Error(request: HttpRequest<any>, next: HttpHandler) {
  // console.log("Handling 401");
  }
 }

可以看出,函数handleServerError负责显示一个错误对话框(它显示),并且应该按照return语句的指示重试失败的请求。

究竟是什么,我做错了,我无法识别。帮助表示赞赏。

标签: angular

解决方案


在这种情况下,我使用 retry(1)

如果发生错误,重试可观察序列特定次数。

/**
 * Return the Observable
 */
return next.handle(request).pipe(
    retry(1), // <-- add this to repeat
    map((event: HttpEvent<any>) => {
        if(event instanceof HttpResponse) {
            console.log('event---->>>', event);
        }
        return event;
    }),
    catchError((error: HttpErrorResponse) => {
        console.log(error);
        if(error.status === 401) {
            this.handle401Error(request, next);
        }
        else if(error.status === 500 || error.statusText === 'Unknown Error') {
          this.handleServerError(request, next, token);
        }
        else {
            return throwError(error);
        }
        return throwError(error)
    })
)

推荐阅读