我使用拦截器根据每个请求的HTTP响应显示错误消息.
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);
})
);
}
在我的项目中,在某些情况下,Web服务器可能暂时不可用,并回复500错误代码.我不希望我的网络应用程序在收到错误后立即显示错误消息,并且我希望它以一秒钟的延迟重试请求几次.
我已经尝试过rxjs重试:
...
.handle(customReq).pipe(retry(5),
...
它没有用,因为它没有延迟.
根据这个答案
How to create an RXjs RetryWhen with delay and limit on tries
我尝试重试时喜欢:
.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));
}),
但它不能按预期工作,它不会进入if条件.
解决方法:
您的代码中有几个错误:
>你是阴影错误变量 – 首先它是一个错误流然后它是一个错误对象.
>使用带延迟的observableThrowError无效.除处理错误的运算符外,错误将绕过每个运算符.
>您正在混合“pipe(operator())”样式运算符和原型样式运算符.operator().
我已经提出了一些改变:
.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)
)
),
主要的变化是通过concatMap的第二个参数跟踪错误计数而不是使用take opeator,这主要用于取消订阅observable,我认为你想要抛出错误.