Angular-所有HTTP重试失败后捕获错误

时间:2019-10-15 11:21:25

标签: angular http rxjs

我正在使用Angular Service从我的API获取数据。在获取数据失败的情况下,我实现了重试功能。现在,当所有重试用尽时,我需要处理错误,但我无法捕获它。

以下是我的代码,

public getInfoAPI(category:string, id:string = "", page:string = "1", limit:string = "10"){
    var callURL : string = '';

    if(!!id.trim() && !isNaN(+id)) callURL = this.apiUrl+'/info/'+category+'/'+id;
    else callURL = this.apiUrl+'/info/'+category;

    return this.http.get(callURL,{
      params: new HttpParams()
        .set('page', page)
        .set('limit', limit)
    }).pipe(
      retryWhen(errors => errors.pipe(delay(1000), take(10), catchError(this.handleError)))//This will retry 10 times at 1000ms interval if data is not found
    );
  }
// Handle API errors
  handleError(error: HttpErrorResponse) {
    console.log("Who's there?");
    if (error.error instanceof ErrorEvent) {
      // A client-side or network error occurred. Handle it accordingly.
      console.error('An error occurred:', error.error.message);
    } else {
      // The backend returned an unsuccessful response code.
      // The response body may contain clues as to what went wrong,
      console.error(
        `Backend returned code ${error.status}, ` +
        `body was: ${error.error}`);
    }
    // return an observable with a user-facing error message
    return throwError(
      'Something bad happened; please try again later.');
  };

我能够以1秒的延迟成功重试10次,但是当重试10次后,我希望无法捕获错误。

enter image description here

注意:

我是Angular的新手,因此,如果您可以建议改进此电话,欢迎您这样做。

4 个答案:

答案 0 :(得分:3)

    return this.http.get(callURL,{
      params: new HttpParams()
        .set('page', page)
        .set('limit', limit)
    }).pipe(
      retryWhen(genericRetryStrategy({maxRetryAttempts: 10, scalingDuration: 1})),
      catchError(this.handleError)
    );

genericRetryStrategy来自此retrywhen resource的地方

export const genericRetryStrategy = ({
  maxRetryAttempts = 3,
  scalingDuration = 1000,
  excludedStatusCodes = []
}: {
  maxRetryAttempts?: number,
  scalingDuration?: number,
  excludedStatusCodes?: number[]
} = {}) => (attempts: Observable<any>) => {
  return attempts.pipe(
    mergeMap((error, i) => {
      const retryAttempt = i + 1;
      // if maximum number of retries have been met
      // or response is a status code we don't wish to retry, throw error
      if (
        retryAttempt > maxRetryAttempts ||
        excludedStatusCodes.find(e => e === error.status)
      ) {
        return throwError(error);
      }
      console.log(
        `Attempt ${retryAttempt}: retrying in ${retryAttempt *
          scalingDuration}ms`
      );
      // retry after 1s, 2s, etc...
      return timer(retryAttempt * scalingDuration);
    }),
    finalize(() => console.log('We are done!'))
  );
};

Stackblitz

答案 1 :(得分:2)

您尝试过retry(10)吗?然后在第二个订阅回调中,您可以处理错误:

return this.http.get(callURL,{
  params: new HttpParams()
    .set('page', page)
    .set('limit', limit)
}).pipe(
  retry(10)
).subscribe((res) => {}, (e) => {
  // handle error
});

答案 2 :(得分:1)

请尝试更改此内容:

}).pipe(
  retryWhen(errors => errors.pipe(delay(1000), take(10), catchError(this.handleError)))
);

对此: 这可能需要对您自己的代码进行调整,但是这种方法对我有用,throwError将被捕获为错误

}).pipe(
  mergeMap(x => {
    if(x == error) return throwError('Error!'); //tweak this for your error
    else return of(x);
  }),
  retryWhen(errors => errors.pipe(delay(1000), take(10))), 
  catchError(error => this.handleError(error)) // change here 
);

并使句柄错误返回可观察到,如:

handleError(err) {
  ..your code
  return of(err); //and NOT return throwError here
}

答案 3 :(得分:0)

根据错误消息,您有CORS问题。您必须在SLIM后端http://www.slimframework.com/docs/v3/cookbook/enable-cors.html

中启用cors