我正在构建一个angular2应用程序。我有一个名为HttpClient的全局服务,它在内置http服务被解雇之前处理所有请求。此服务还通过检查状态代码处理我的所有响应错误:
import { Injectable } from '@angular/core';
import { Headers, Http, Response, } from '@angular/http';
import { MessageProvider } from '../../providers/message/message.provider'
@Injectable()
export class HttpClient {
private webApi = 'http://localhost:8080/api/v1/';
constructor(
private http: Http,
private messageProvider: MessageProvider) { }
get(url: string): Promise<Response> {
return this.http.get(this.webApi + url, {headers: this.createAuthorizationHeader()})
.toPromise()
.catch(this.handleError.bind(this));
}
post(url: string, data: Object): Promise<Response> {
return this.http.post(this.webApi + url, data, {headers: this.createAuthorizationHeader()})
.toPromise()
.catch(this.handleError.bind(this));
}
put(url: string, data: Object): Promise<Response> {
return this.http.put(this.webApi + url, data, {headers: this.createAuthorizationHeader()})
.toPromise()
.catch(this.handleError.bind(this));
}
delete(url: string): Promise<Response> {
return this.http.delete(this.webApi + url, {headers: this.createAuthorizationHeader()})
.toPromise()
.catch(this.handleError.bind(this));
}
private handleError (error: any) {
var status: number = error.status;
if(status == 401) {
this.messageProvider.setMessage(error);
this.messageProvider.message.text = "You have to be logged in to reach this page.";
}
let errMsg = (error.message)
? error.message
: status
? `${status} - ${error.statusText}`
: 'Server error';
console.error(errMsg); // log to console instead
return error;
}
private createAuthorizationHeader() {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Accept', 'application/json');
if (localStorage.getItem('token'))
headers.append('Authorization', 'Bearer ' + localStorage.getItem('token'));
return headers;
}
}
现在,让我们假装调用组件是关于登录的:
import { Component, Input, OnInit, OnDestroy } from '@angular/core';
import { Router } from '@angular/router';
import { Login } from '../../core/classes/login/login'
import { AuthenticationProvider } from '../../providers/authentication/authentication.provider'
import { MessageProvider } from '../../providers/message/message.provider'
@Component({
selector: 'my-login',
templateUrl: 'app/components/login/login.component.html'
})
export class LoginComponent implements OnInit, OnDestroy {
@Input() login: Login;
error: any;
constructor(
private authProvider: AuthenticationProvider,
private route: Router,
private messageProvider: MessageProvider) { }
ngOnInit() {
this.login = new Login();
}
ngOnDestroy() {
this.messageProvider.setDefault();
}
onSubmit() {
this.authProvider.login(this.login)
.then(auth => {
if (this.authProvider.isAdmin())
this.route.navigateByUrl('admin/users');
else if (this.authProvider.isLoggedIn())
this.route.navigateByUrl('/');
})
.catch(error => {console.log(error);});
}
}
在这种情况下,我不希望来自HttpClient的错误(“您必须登录才能访问此页面。”),而是更加自定义的消息,例如“找不到用户”。我知道我可以做类似以下的事情,但不再有任何错误:
onSubmit() {
this.authProvider
.login(this.login)
.then(auth => {
if (this.authProvider.isAdmin())
this.route.navigateByUrl('admin/users');
else if (this.authProvider.isLoggedIn())
this.route.navigateByUrl('/');
})
.catch(error => {
var status: number = error.status;
if(status == 401) {
this.messageProvider.setMessage(error);
this.messageProvider.message.text = "No user found.";
}
});
}
那么有没有办法在HttpClient中的catch()函数中引起另一个错误?所以我可以在LoginComponent中再次处理错误。
答案 0 :(得分:3)
我认为你可以使用catch方法来实际“映射”你的错误。如果您还要更新messageProvider
,那么您可以...
.catch(error => {
var status: number = error.status;
var newError = {};
if(status == 401) {
this.messageProvider.setMessage(error);
this.messageProvider.message.text = "No user found.";
newError.errorMessage = "No user found.";
}
throw newError;
});
用这个例子证实:
var obs = Observable.of(12);
obs.map((value) => {
throw "blah";
}).catch((error) => {
if(error === "blah") {
throw "baz";
} else {
return Observable.of("Hello");
}
}).subscribe((value) => {
console.log("GOOD: " + value);
}, (error) => {
console.log("ERR: " + error);
});
//Logs ERR: baz