我正在使用拦截器来处理未经授权的HTTP请求,该请求将显示模式或路由到登录页面。当拦截器处理错误时,我不希望发出原始请求的服务或组件也处理该错误。我确实希望组件或服务错误处理能够引发非401错误。
在我的拦截器中,我正在使用RxJS catchError
捕获错误并检查错误详细信息。如果拦截器不会处理它,我只是将其与throwError
一起抛出,这似乎可以正常工作。问题是我需要停止错误传播。如果不返回任何内容,则会出现以下错误:
错误TypeError:您在期望流的位置提供了“ undefined”。 您可以提供一个Observable,Promise,Array或Iterable。
使用of()
返回一个空的Observable几乎可以,但是在加载应用程序时,控制台中出现以下错误。
错误错误:未捕获(按承诺):空错误:顺序中没有元素
我不知道原因或解决方法。我应该如何在拦截器中终止执行,从而基本上完成可观察的工作?这是我的代码:
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor (
private router: Router,
private sessionService: SessionService
) {}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
request = request.clone()
return next.handle(request).pipe(
catchError((err: any) => {
if (err instanceof HttpErrorResponse) {
if (err.status === 401 && this.router.url === '/') {
this.router.navigateByUrl('/login')
} else if (err.status === 401 && !/^\/activate-account/.test(this.router.url) && !/^\/log-?[i,I]n/.test(this.router.url)) {
this.sessionService.setSessionExpired()
}
return of()
} else {
return throwError(err)
}
})
)
}
}
答案 0 :(得分:1)
为什么不能尝试Observable.empty()。它将停止传播并将处理程序返回到调用服务。
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor (
private router: Router,
private sessionService: SessionService
) {}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
request = request.clone()
return next.handle(request).pipe(
catchError((err: any) => {
if (err instanceof HttpErrorResponse) {
if (err.status === 401 && this.router.url === '/') {
this.router.navigateByUrl('/login')
} else if (err.status === 401 && !/^\/activate-account/.test(this.router.url) && !/^\/log-?[i,I]n/.test(this.router.url)) {
this.sessionService.setSessionExpired()
}
return Observable.empty();
} else {
return throwError(err)
}
})
)
}
}
答案 1 :(得分:0)
拦截器期望您使用catchError
传输的return语句。如果不这样做,就不会尊重拦截器的签名,因此会出错。
为避免这种情况,请始终返回抛出的可观察值。您可以返回throwError(undefined)
,并且在错误处理中,如果看到错误是未定义的,则根本就不对待它。您甚至可以走得更远,并使用Rx通过.pipe(filter(err => !!err))
过滤未定义的错误。
答案 2 :(得分:0)
问题似乎是由于在返回空的可观察对象之前导航离开了。我已将return语句移到特定的if条件中,以便在调用throwError(err)
之后可以返回this.router.navigateByUrl
,否则返回一个空的observable。我还使用了EMPTY
的可观察常数(如Suresh Kumar Ariya所建议)
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor (
private router: Router,
private sessionService: SessionService
) {}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
request = request.clone()
return next.handle(request).pipe(
catchError((err: any) => {
if (err instanceof HttpErrorResponse) {
if (err.status === 401 && this.router.url === '/') {
this.router.navigateByUrl('/login')
return throwError(err)
} else if (err.status === 401 && !/^\/activate-account/.test(this.router.url) && !/^\/log-?[i,I]n/.test(this.router.url)) {
this.sessionService.setSessionExpired()
return EMPTY
} else {
return throwError(err)
}
} else {
return throwError(err)
}
})
)
}
}