Angular 2 RxJS Observable: RetryWhen filter retry on error Status

一世执手 提交于 2019-12-17 20:28:02

问题


I am using Angular 2 HTTP library which returns an observable. I want to implement retry on certain error status/code.

I have an issue, if the error is not 429, Observable.of(error) is getting executed in error case to retry, but when all your 2 retry fails the execution of flow goes to success block instead of catch block.

How to make execution of flow to catch block in all retry fails?

    return this.http.get(url,options)
           .retryWhen((errors) => {
                      return errors
                            .mergeMap((error) => (error.status === 429) ? Observable.throw(error) : Observable.of(error))
                            .take(2);
                     })
                       .toPromise()
                       .then((res:Response) => console.log('In Success Block'))
                       .catch((res) => this.handleError(res));

will it resolve my problem

        return this.http
  .post(url, JSON.stringify(body), requestOptions).retryWhen((errors) => {
    return errors
      .mergeMap((error) => (error.status === 404) ? Observable.throw(error) : Observable.of(error))
      .take(2);
  }).map((res:Response) =>{
    if (res.status === 200)
      return res;
    else
      return Observable.throw(res);
  })
  .toPromise();

回答1:


A little late to the party but, I recently implemented a similar behaviour. Here is my solution:

  post<T>(serviceUrl: string, data: any): Observable<T> {
    return Observable.defer(() => {
        return super.post<T>(serviceUrl, data);
    }).retryWhen((error) => {
        return this.refresh(error);
    });
}

And the refresh function:

refresh(obs: Observable<any>): Observable<any> {
    return obs
        .switchMap((x: any) => {
            if (x.status === 401) {
                return Observable.of(x);
            }
            return Observable.throw(x);
        })
        .scan((acc, value) => {
            return acc + 1;
        }, 0)
        .takeWhile(acc => acc < 3)
        .flatMap(() => {
            console.log('Token refresh retry');
            return this.tokenRefreshService.refreshToken();
        });
}

The use case is that whenever I make an HTTP request and get a 401 response, I want to do a token refresh and then retry the initial request with the new token. When a 401 occurs I use switchMap to return a new Observable, otherwise, I return an Observable.throw(x) that stops the retry logic from being executed.

And the calling code looks like this (where error is called whenever you return an Observable.throw(x)):

 this.http.post(x).subscribe(response => {
      ...
        }
    }, error => {
        ...
        }
    });


来源:https://stackoverflow.com/questions/39928183/angular-2-rxjs-observable-retrywhen-filter-retry-on-error-status

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!