J'utilise un intercepteur pour afficher les messages d'erreur sur l'affichage en fonction de la réponse HTTP pour chaque demande.
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const customReq = request.clone({
//headers: request.headers.set('app-language', 'en')
});
return next
.handle(customReq).pipe(
tap((ev: HttpEvent<any>) => {
if (ev instanceof HttpResponse) {
// processing request
}
}),
catchError(response => {
if (response instanceof HttpErrorResponse) {
switch (response.status) {
case 0:
// server API connection error show
break;
case 403:
// error Token Invalid and Redirect to logout
break;
case 401:
// error Token Invalid and Redirect to logout
break;
case 502:
// Bad gateway error
break;
case 500:
// internal server error
break;
}
}
// return next.handle(request);
return observableThrowError(response);
})
);
}
Dans mon projet, le serveur Web pourrait être indisponible pendant une seconde dans certains cas et répondre à un code d'erreur 500. Je ne veux pas que mon application Web affiche un message d'erreur immédiatement après avoir reçu une erreur et je veux qu'elle réessaye la demande plusieurs fois avec un délai comme une seconde.
J'ai déjà essayé de réessayer rxjs:
...
.handle(customReq).pipe(retry(5),
...
ce n'est pas utile car il n'a pas de retard. basé sur cette réponse Comment créer un RXjs RetryWhen avec délai et limite sur les essais
J'ai essayé de réessayer
.handle(customReq).pipe(
tap((ev: HttpEvent<any>) => {
if (ev instanceof HttpResponse) {
console.log('###processing response', ev, this.location);
}
}),
retryWhen(error => {
return error
.flatMap((error: any) => {
if (error.status == 400) {
return Observable.of(error.status).delay(1000);
}
if (error.status == 0) {
return observableThrowError(error).delay(1000);
}
return observableThrowError(error);
})
.take(5)
.concat(observableThrowError(error));
}),
mais cela ne fonctionne pas comme prévu et ne rentre pas dans les conditions if.
Il y a plusieurs erreurs dans votre code:
error
- c'est d'abord un flux d'erreur, puis un objet erreur.observableThrowError
avec delay
n'a aucun effet. L'erreur contournera tous les opérateurs, sauf ceux qui traitent d'erreur.pipe(operator())
" et les opérateurs de style prototype .operator()
.J'ai suggéré quelques changements:
.handle(customReq).pipe(
tap((ev: HttpEvent<any>) => {
if (ev instanceof HttpResponse) {
console.log('###processing response', ev, this.location);
}
}),
retryWhen(errors => errors
.pipe(
concatMap((error, count) => {
if (count < 5 && (error.status == 400 || error.status == 0)) {
return Observable.of(error.status);
}
return observableThrowError(error);
}),
delay(1000)
)
),
La principale modification consiste à suivre le nombre d'erreurs via le deuxième argument de concatMap
au lieu d'utiliser take
opeator, ce qui est principalement utile pour se désabonner de l'observable et je pense que vous souhaitez plutôt lancer une erreur.
Le blog suivant vous explique comment réessayer les requêtes HTTP qui ont échoué. Il vous donne également différentes stratégies sur la façon de gérer les tentatives.