Angular 8 Http 拦截器 return 值
Angular8 HttpInterceptor return value
我有一个基本的 HttpInterceptor,我在其中使用 rxjs retryWhen,以便在出现服务故障时重试一定次数。如果服务调用已达到最大重试次数,那么我想将其反馈给最初发起服务调用的方法。
我的问题是,我如何才能return 控制回 http 调用的原始发起者?
我需要这样做以便在一个地方(拦截器)集中控制处理重试,我希望能够回调到调用函数中的 success/failure 方法。
我的问题是错误被全局错误处理程序吞没了,没有任何内容返回给我的调用者。
示例:
this.MyServiceCall()
.pipe(
map((result) => {
console.log('this is called when the service returns success');
}),
)
// If there is an error, then how can I show it?
})
}
export class HttpRetryInterceptorService implements HttpInterceptor {
constructor() { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).pipe(
retryWhen(errors => errors
.pipe(
concatMap((err:HttpErrorResponse, count) => iif(
() => (count < 3),
of(err).pipe(
map(()=>{
console.log(count.toString())
}),
delay((2 + Math.random()) ** count * 200)),
throwError(err)
))
))
);
}
}
尝试使用 catchError()
this.MyServiceCall()
.pipe(
map((result) => {
console.log('this is called when the service returns success');
}),
catchError((error) => {
// Do something and return either an observable or rethrow the error
return throwError(error);
})
);
https://www.learnrxjs.io/operators/error_handling/catch.html
我认为您可以使用 catchError
运算符。
您仍然可以在一个地方处理错误(即:您的拦截器)并通过 throwing an error in the observable 将错误委托给调用者您的服务将订阅。
注意:如果在拦截器中使用throwError
操作符,TS应该会报错:
intercept (req: HttpRequest<any>, next: HttpHandler) {
//~~~~~~
const foo = false;
return next.handle(req)
.pipe(
map(ev => foo ? ev : throwError('err!')),
)
}
错误是:
Type Observable < never > is not assignable to type 'HttpEvent'.
并且 HttpEvent
类型如下所示:
export type HttpEvent<T> =
HttpSentEvent | HttpHeaderResponse | HttpResponse<T>| HttpProgressEvent | HttpUserEvent<T>;
因此,那里不允许出现错误..但这是我在 this SO post.
中找到的解决方法
intercept (req: HttpRequest<any>, next: HttpHandler) {
const foo = false;
return next.handle(req)
.pipe(
map(e => {
if (e instanceof HttpResponse && !foo) {
throw new HttpErrorResponse({
error: 'err'
});
}
return e;
})
)
}
现在,delegated 错误应该在您的服务的 catchError
回调中被捕获。
this.MyServiceCall()
.pipe(
map((result) => {
console.log('this is called when the service returns success');
}),
catchError(err => {
// Do something with this error...
})
)
编辑
拦截器抛出错误也可以通过这种方式实现:
intercept (req: HttpRequest<any>, next: HttpHandler) {
const foo = false;
return next.handle(req)
.pipe(
mergeMap(e => {
if (!foo) {
return throwError('err');
}
return of(e);
}),
)
}
我错过了 throwError
returns 可观察到的事实 :D.
我有一个基本的 HttpInterceptor,我在其中使用 rxjs retryWhen,以便在出现服务故障时重试一定次数。如果服务调用已达到最大重试次数,那么我想将其反馈给最初发起服务调用的方法。
我的问题是,我如何才能return 控制回 http 调用的原始发起者? 我需要这样做以便在一个地方(拦截器)集中控制处理重试,我希望能够回调到调用函数中的 success/failure 方法。
我的问题是错误被全局错误处理程序吞没了,没有任何内容返回给我的调用者。
示例:
this.MyServiceCall()
.pipe(
map((result) => {
console.log('this is called when the service returns success');
}),
)
// If there is an error, then how can I show it?
})
}
export class HttpRetryInterceptorService implements HttpInterceptor {
constructor() { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).pipe(
retryWhen(errors => errors
.pipe(
concatMap((err:HttpErrorResponse, count) => iif(
() => (count < 3),
of(err).pipe(
map(()=>{
console.log(count.toString())
}),
delay((2 + Math.random()) ** count * 200)),
throwError(err)
))
))
);
}
}
尝试使用 catchError()
this.MyServiceCall()
.pipe(
map((result) => {
console.log('this is called when the service returns success');
}),
catchError((error) => {
// Do something and return either an observable or rethrow the error
return throwError(error);
})
);
https://www.learnrxjs.io/operators/error_handling/catch.html
我认为您可以使用 catchError
运算符。
您仍然可以在一个地方处理错误(即:您的拦截器)并通过 throwing an error in the observable 将错误委托给调用者您的服务将订阅。
注意:如果在拦截器中使用throwError
操作符,TS应该会报错:
intercept (req: HttpRequest<any>, next: HttpHandler) {
//~~~~~~
const foo = false;
return next.handle(req)
.pipe(
map(ev => foo ? ev : throwError('err!')),
)
}
错误是:
Type Observable < never > is not assignable to type 'HttpEvent'.
并且 HttpEvent
类型如下所示:
export type HttpEvent<T> =
HttpSentEvent | HttpHeaderResponse | HttpResponse<T>| HttpProgressEvent | HttpUserEvent<T>;
因此,那里不允许出现错误..但这是我在 this SO post.
中找到的解决方法intercept (req: HttpRequest<any>, next: HttpHandler) {
const foo = false;
return next.handle(req)
.pipe(
map(e => {
if (e instanceof HttpResponse && !foo) {
throw new HttpErrorResponse({
error: 'err'
});
}
return e;
})
)
}
现在,delegated 错误应该在您的服务的 catchError
回调中被捕获。
this.MyServiceCall()
.pipe(
map((result) => {
console.log('this is called when the service returns success');
}),
catchError(err => {
// Do something with this error...
})
)
编辑
拦截器抛出错误也可以通过这种方式实现:
intercept (req: HttpRequest<any>, next: HttpHandler) {
const foo = false;
return next.handle(req)
.pipe(
mergeMap(e => {
if (!foo) {
return throwError('err');
}
return of(e);
}),
)
}
我错过了 throwError
returns 可观察到的事实 :D.