问题描述
为本机Angular http类提供了一个AuthHttp包装器,它自动包含http授权标头与每个请求。在我的服务中,我通常会像这样调用一个后端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(主体);
errMsg =`$ {error.status} - $ {error.statusText || ''} $ {err}`;
} else {
errMsg = error.message? error.message:error.toString();
}
//如果JWT过期打开一个新窗口再次登录
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类来自动捕获每个请求的错误,然后在特殊情况下,我可以逐个添加自定义捕获逻辑?
I可以从另一个文件导出方法,并将其导入我的每个服务,但我认为必须有一个更好的方法。感谢任何建议。
更新:我结束了从Angle2-jwt扩展AuthHttp类。
<$ p $来自'@ angular / http'的p>
import {Http,RequestOptions,Response,Request,RequestOptionsArgs};
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){
//错误处理然后重新抛出错误
return Observable.throw(error);
}
}
你可以像AuthHTTP Wrapper一样创建CustomAuthHttp的定制服务。喜欢wrapper添加标题,在CustomAuthHttp中可以捕获错误。然后在你的代码中注入CustomAuthHttp而不是AuthHTTP并使用。
@Injectable()
export class CustomAuthHttp {
构造函数(私有http:AuthHttpWrapper){}
get(url:string){
return this.http.get(url)
.catch res => this.handleError(res));
}
private handleError(error:Response | any){
//你的代码
return Observable.throw('');
}
}
angular2-jwt provides an AuthHttp wrapper for the native Angular http class that automatically includes the http authorization header with each request. In my services I am usually calling a backend api like this
getThings(): Observable<Thing[]> {
return this.http.get(environment.apiEndpoint + '/things')
.map(res => res.json().data)
.catch(res => this.handleError(res));
}
with an error handler like
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);
}
I keep repeating the handleError method in all my services and I would like to know if there is a way to make this DRY. Is there a way to define a generic error handler for all http requests?
I'd like to avoid having to call catch each time if possible. Is there a way to extend the http class to automatically catch errors on each request and then in special situations I can add custom catch logic on a case by case basis?
I could export the method from another file and import it in each of my services but I think there has got to be a better way. Thanks for any suggestions.
UPDATE: I ended up extending the AuthHttp class from angular2-jwt.
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);
}
}
You can create custom service CustomAuthHttp like AuthHTTP Wrapper. Like wrapper adds header, in CustomAuthHttp you can catch error. Then in your code inject CustomAuthHttp instead of AuthHTTP and use.
@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('');
}
}
这篇关于角色中的通用http错误处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!