【发布时间】:2018-01-23 10:21:30
【问题描述】:
当我遇到某个异常时,我正在尝试刷新 JWT 令牌,而当它是另一个异常时,我的 ErrorHandler 应该处理它们。
我有一段代码,一个用于令牌刷新的代码,还有一段用于异常处理程序的代码,但我无法将它们组合在一起。
问题是我不能抛出异常并用我的 ErrorHandler 在 observable 中捕获它。
这是我可以用来刷新令牌的代码。当它失败时,它会检查错误代码是否为token_expired,如果是,它将刷新令牌并重试请求。
export class HttpErrorService extends Http {
constructor(backend: XHRBackend, defaultOptions: RequestOptions) {
super(backend, defaultOptions);
}
request(url: string | Request, options?: RequestOptionsArgs, disableRefresh = false): Observable<Response> {
return super.request(url, options).catch((error: Response) => {
// Refresh token on token_expired exception.
if (!disableRefresh && error.status === 401 && error.json().error.code === 'token_expired') {
return this.renewToken().flatMap((response) => {
const res = response.json();
// Replace the token in storage.
localStorage.setItem('__token', res.data.token);
// Replace request the token with the new one.
if (url instanceof Request) {
url.headers.set('Authorization', 'Bearer ' + res.data.token);
} else if (options) {
options.headers.set('Authorization', 'Bearer ' + res.data.token);
}
// To prevent a loop disable refreshing at the next request.
return this.request(url, options, true);
});
}
// Here I want to throw the exception.
// I need to be able to catch it with my exception handler.
// throw error; doesn't work.
return Observable.throw(error);
});
}
private getBaseUrl(): string {
return environment.base_uri;
};
renewToken(): Observable<Response> {
const headers = new Headers();
headers.append('Authorization', 'Bearer ' + localStorage.getItem('__token'))
return this.post(this.getBaseUrl() + '/auth/refresh', {}, {headers: headers});
}
}
上面唯一的坏处是我无法在我的异常处理程序中捕获异常。
下面的代码可以抛出可以被 ErrorHandler 捕获的异常。但我不知道如何在一次调用中刷新令牌...
export class HttpErrorService extends Http {
constructor(backend: XHRBackend, defaultOptions: RequestOptions) {
super(backend, defaultOptions);
}
request(url: string | Request, options?: RequestOptionsArgs, disableRefresh = false): Observable<Response> {
return Observable.create(observer => {
super.request(url, options).subscribe(
res => observer.next(res),
err => {
if (!disableRefresh && err.status === 401 && err.json().error.code === 'token_expired') {
// I can't return this.renewToken()...
}
observer.error(err);
throw new HttpException(err); // this is getting catched by the ErrorHandler
},
() => observer.complete);
});
}
private getBaseUrl(): string {
return environment.base_uri;
};
renewToken(): Observable<Response> {
const headers = new Headers();
headers.append('Authorization', 'Bearer ' + localStorage.getItem('__token'))
return this.post(this.getBaseUrl() + '/auth/refresh', {}, {headers: headers});
}
}
我的错误处理程序只包含一个console.log()。
https://angular.io/api/core/ErrorHandler
我怎样才能让它工作?
【问题讨论】:
-
也可以在实际调用请求函数和ErrorHandler的地方加上代码吗?
-
@trungk18 我正在重写 Http 类,所以每个 http 请求都使用 request 函数。它是默认的 Http 库。 ErrorHandler 只是一个
console.log(); -
嗨 Jan,你能在你的第一个代码块上尝试“throw Observable.throw(error)”而不是“return Observable.throw(error)”吗?
-
@trungk18 它到达订阅错误但它没有到达异常处理程序,我的第二个“代码”确实到达了它们。我使用订阅错误向用户显示错误消息。以及处理错误的异常处理程序。
-
我不太擅长 rxjs,所以我们可能需要一些专家建议:D
标签: angular http jwt angular2-observables