Angular 中的通用 http 错误处理
Generic http error handling in Angular
angular2-jwt 为本机 Angular http class 提供了一个 AuthHttp 包装器,它自动包含每个请求的 http 授权 header。在我的服务中,我通常这样调用后端 api
getThings(): Observable<Thing[]> {
return this.http.get(environment.apiEndpoint + '/things')
.map(res => res.json().data)
.catch(res => this.handleError(res));
}
使用像
这样的错误处理程序
private handleError(error: Response | any) {
let errMsg: string;
if (error instanceof Response) {
const body = error.json() || '';
const err = body.error || JSON.stringify(body);
errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
} else {
errMsg = error.message ? error.message : error.toString();
}
// If JWT is expired open a new window to log in again
if (errMsg.indexOf('No JWT present or has expired') !== -1) {
window.open(environment.apiEndpoint + '/loginToApp?expired', '_blank', 'height=570,width=520');
}
console.error(error);
return Observable.throw(errMsg);
}
我一直在我的所有服务中重复 handleError 方法,我想知道是否有办法让这个 DRY。有没有办法为所有 http 请求定义一个通用的错误处理程序?
我希望尽可能避免每次都调用 catch。有没有办法扩展 http class 以自动捕获每个请求的错误,然后在特殊情况下我可以根据具体情况添加自定义捕获逻辑?
我可以从另一个文件导出该方法并将其导入到我的每个服务中,但我认为必须有更好的方法。感谢您的任何建议。
更新:我最终从 angular2-jwt 扩展了 AuthHttp class。
import { Http, RequestOptions, Response, Request, RequestOptionsArgs } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
import { AuthHttp, AuthConfig } from 'angular2-jwt';
export class ApiHttp extends AuthHttp {
public request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
return super.request(url, options).catch(res => this.handleError(res));
}
private handleError(error: Response | any) {
// error handling then rethrow the error
return Observable.throw(error);
}
}
您可以创建自定义服务 CustomAuthHttp,例如 AuthHTTP Wrapper。就像 wrapper 添加 header,在 CustomAuthHttp 中你可以捕获错误。然后在您的代码中注入 CustomAuthHttp 而不是 AuthHTTP 并使用。
@Injectable()
export class CustomAuthHttp {
constructor(private http: AuthHttpWrapper) { }
get(url: string) {
return this.http.get(url)
.catch(res => this.handleError(res));
}
private handleError(error: Response | any) {
// your code
return Observable.throw('');
}
}
angular2-jwt 为本机 Angular http class 提供了一个 AuthHttp 包装器,它自动包含每个请求的 http 授权 header。在我的服务中,我通常这样调用后端 api
getThings(): Observable<Thing[]> {
return this.http.get(environment.apiEndpoint + '/things')
.map(res => res.json().data)
.catch(res => this.handleError(res));
}
使用像
这样的错误处理程序private handleError(error: Response | any) {
let errMsg: string;
if (error instanceof Response) {
const body = error.json() || '';
const err = body.error || JSON.stringify(body);
errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
} else {
errMsg = error.message ? error.message : error.toString();
}
// If JWT is expired open a new window to log in again
if (errMsg.indexOf('No JWT present or has expired') !== -1) {
window.open(environment.apiEndpoint + '/loginToApp?expired', '_blank', 'height=570,width=520');
}
console.error(error);
return Observable.throw(errMsg);
}
我一直在我的所有服务中重复 handleError 方法,我想知道是否有办法让这个 DRY。有没有办法为所有 http 请求定义一个通用的错误处理程序?
我希望尽可能避免每次都调用 catch。有没有办法扩展 http class 以自动捕获每个请求的错误,然后在特殊情况下我可以根据具体情况添加自定义捕获逻辑?
我可以从另一个文件导出该方法并将其导入到我的每个服务中,但我认为必须有更好的方法。感谢您的任何建议。
更新:我最终从 angular2-jwt 扩展了 AuthHttp class。
import { Http, RequestOptions, Response, Request, RequestOptionsArgs } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
import { AuthHttp, AuthConfig } from 'angular2-jwt';
export class ApiHttp extends AuthHttp {
public request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
return super.request(url, options).catch(res => this.handleError(res));
}
private handleError(error: Response | any) {
// error handling then rethrow the error
return Observable.throw(error);
}
}
您可以创建自定义服务 CustomAuthHttp,例如 AuthHTTP Wrapper。就像 wrapper 添加 header,在 CustomAuthHttp 中你可以捕获错误。然后在您的代码中注入 CustomAuthHttp 而不是 AuthHTTP 并使用。
@Injectable()
export class CustomAuthHttp {
constructor(private http: AuthHttpWrapper) { }
get(url: string) {
return this.http.get(url)
.catch(res => this.handleError(res));
}
private handleError(error: Response | any) {
// your code
return Observable.throw('');
}
}