3 votes

Angular 2 RxJS Observable : RetryWhen filtre de réessai sur erreur Statut

J'utilise la bibliothèque HTTP d'Angular 2 qui renvoie un observable. Je veux implémenter la relance sur certains statuts/codes d'erreur.

J'ai un problème, si l'erreur n'est pas 429, Observable.of(error) est exécuté en cas d'erreur pour réessayer, mais lorsque vos deux réessais échouent, l'exécution du flux passe au bloc success au lieu du bloc catch.

Comment faire en sorte que l'exécution du flux vers le bloc de capture dans tous les échecs de réessai ?

    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));

Cela résoudra-t-il mon problème ?

        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();

11voto

Radu Cojocari Points 1002

J'arrive un peu tard dans la soirée mais j'ai récemment mis en place un comportement similaire. Voici ma solution :

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

Et la fonction de rafraîchissement :

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();
        });
}

Le cas d'utilisation est le suivant : chaque fois que je fais une demande HTTP et que je reçois une réponse 401, je veux rafraîchir le jeton et réessayer la demande initiale avec le nouveau jeton. Lorsqu'une réponse 401 se produit, j'utilise switchMap pour renvoyer un nouvel Observable, sinon, je renvoie un Observable.throw(x) qui empêche l'exécution de la logique de réessai.

Et le code d'appel ressemble à ceci (où error est appelé chaque fois que vous renvoyez un Observable.throw(x)) :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X