在401响应中完全忽略了CatchError。
我有httpInterceptor来处理oauth2身份验证。
相关代码是:
import { filter, take, switchMap, map, catchError } from 'rxjs/operators';
//ommited
if (authService.hasRefreshToken()) {
return authService.doRefreshToken().pipe(switchMap(tokenResponse => {
const accessToken = tokenResponse['access_token'];
this.tokenSubject.next(accessToken);
return <Observable<HttpEvent<any>>> next.handle(this.addToken(req, accessToken));
}), catchError((err: any, caught: any) => {
console.log(err)
return Observable.throw(err);
})
)
}
AuthService类:
export class AuthService {
doRefreshToken() {
//ommited
return this.httpClient.post(environment.baseUrl + this.tokenEndpoint, null, requestOptions).pipe(
map(tokenResponse => {
this.saveToken(tokenResponse);
return tokenResponse;
}),
catchError((err: any, caught: Observable<Object>) => {
//refreshing token failed (refrech token invalid or expired) redirect to login and wipe everything
this.logout();
return Observable.throw(err);
}));
}
}
对于200响应,一切正常,但401错误完全被忽略。 我是否以错误的方式使用这个新的catch错误?
P.S。这段代码用普通的旧捕获工作得很好,但现在当我迁移到angular6管道和catchError时,同样的东西就不起作用了。
编辑:
catchError上的断点显示
&#34; SyntaxError:意外的输入结束 在AuthService.push ../ src / app / common / auth / auth.service.ts.AuthService.doRefreshToken
服务器的实际响应是:
{
"error" : "invalid_token",
"error_description" : "Refresh token expired"
}
标题:
Request Method: POST
Status Code: 401
答案 0 :(得分:0)
我遇到了catchError
函数被完全忽略的同一问题。由于在官方Angular documentation中描述的@SeaBiscuit使用的这种简单直接的代码不起作用,因此我放弃了该方法来处理错误响应,而转而使用HttpInterceptors。那行得通!
Luuk Gruijs在他的文章Global HTTP error catching in Angular 4.3+中的指导启发了我,将下面显示的ErrorInterceptor
添加到了我的代码中。
诚然,下面的拦截器可能并不完美,但是处理拦截器中错误的最重要部分归结为:
next.handle(request).pipe(tap(
(event: HttpEvent<any>) => { },
(error: any) => {
// Handle errors here!
}
))
以下是我实施的详细信息:
export class ErrorInterceptor implements HttpInterceptor {
constructor() { }
intercept (request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (request.method !== 'GET') {
return next.handle(request);
}
const subject = new AsyncSubject<HttpEvent<any>>();
next.handle(request)
.pipe(
tap((event: HttpEvent<any>) => {
// Let HttpResponses pass through interceptor without interaction
if (event instanceof HttpResponse) {
subject.next(event);
subject.complete();
}
}, (error: any) => {
if (error instanceof HttpErrorResponse) {
const errorEvent = new HttpResponse({
body: {
message: error.error.message,
status: error.status,
statusText: error.statusText
}
});
subject.next(errorEvent);
subject.complete();
}
})
).subscribe();
return subject;
}
}
我还修改了服务,以接受手动创建的响应正文:
return this.http.get<MyObjI | ErrorI>(url, {params});
...,其中ErrorI
是:
export interface ErrorI {
message: string;
status: number;
statusText: string;
}
希望在拦截器中处理错误也能帮到您!
答案 1 :(得分:0)
Observable.throw()
不能在return语句中使用。
这就是为什么在AuthService.doRefreshToken
上出现语法错误的原因
Observable.throw()
引发错误,这就是为什么不允许您在return
语句中使用它的原因。
与以下内容相同
return throw Error("")
您可以轻松地从ESlint抱怨。
无论如何,由于这是一个古老的问题,您应该使用新的API,但我希望这可以为旧的rxjs API的用户提供帮助。