Angular 4:如何将应用级http错误正确处理为Observable错误?
Angular 4: How to properly handle app level http error as Observable error?
我使用 HTTP API returns 应用级错误通过 json where status == 'error'.
在我的注册服务中,我这样做了:
return this.userService
.create(user)
.map(
json => {
console.log(json);
if (json.status=='error') {
console.log('error return throw');
return Observable.throw('Credentials mismatch or not existing');
}
const user = json.data as User;
return user;
},
err => {
console.log(err);
}
);
在我的 singUp.component 中,我这样做了:
onSubmit() {
// blahblah
this.si
.signUp(this.credentials.emailAddress, this.credentials.password, this.credentials.zipCode)
.subscribe(
user => {
console.log(user);
console.log(`SignUpComponent.onSubmit() found user.userId ${user.userId}`);
this.router.navigate(['signin']);
},
err => {
this.errorMessage = `*** SignUpComponent: Error while signing up {err}`;
console.error('*** SignUpComponent: Error while signing up', err);
this.resume();
//this.router.navigate(['signup']);
});
this.ngOnChanges();
}
不幸的是,当服务 returns 出错时(使用 Observable.throw()),组件不会触发 err 闭包但用户闭包将 Observable.throw 作为用户参数。
我希望能触发 err 闭包。
我在那里缺少什么?
更新:这是我得到的:
[Log] SigninService.signUp, zipCode=
[Log] {data: null, status: "error", message: "Error user create: - missing id API usage v1b3: Tu…ate\"}↵post: []↵.↵", ws: "v1b3: Tuesday, August 25th 2017 20h20 @ Tanger"}
[Log] error return throw
[Log] ErrorObservable {_isScalar: false, error: "Credentials mismatch or not existing", scheduler: undefined, _subscribe: function, …}
[Log] SignUpComponent.onSubmit() found user.userId undefined
为了避免您遇到的问题,我认为您只需要在没有 return 和 的情况下执行 throw 'Credentials mismatch or not existing'
可观察 部分。在执行可观察对象期间引发的任何错误都将作为错误传播到当前 Observable
.
目前,您只是将 json 响应替换为 Observable
,这不是您想要的。
理想情况下,服务器应该 return 错误响应而不是 json 带有错误消息的响应,后者会触发订阅中的 error
处理程序。
你在用户回调中处理异常,这意味着它已成功执行,在这种情况下 Observable.throws
不会真正充当异常。为了实现这一点,您必须使用必须替换 return Observable.throw("Credentials mismatch or not existing")
的 throw new Error("Credentials mismatch or not existing")
;请看这个:
我最终想出了以下解决方案,扩展了以下事实:1) 使用 throw new Error() 我仍然可以 return Observable 和 2) 当错误抛出时,订阅完成参数不会触发,需要使用 finally() 调用如下:
注册服务:
create(user: User): Observable<User> {
const wsUrl = `${this.wsApi}m=create&id=${user.id}`; // URL to web api
return this.http.post(wsUrl, JSON.stringify(user), { headers: this.headers })
.retry(3)
.map(res => {
const json = res.json() as any;
if (json.status=='error') throw new Error(json.message);
return json.data as User;
});
}
注册组件:
onSubmit() {
// blahblah
this.progressing = true;
this.si
.signUp(this.credentials.emailAddress, this.credentials.password, this.credentials.zipCode)
.finally(() => setTimeout(() => this.progressing = false, 1000))
.subscribe(
user => this.router.navigate(['signin']),
err => this.errorMessage = err
);
this.ngOnChanges();
}
我使用 HTTP API returns 应用级错误通过 json where status == 'error'.
在我的注册服务中,我这样做了:
return this.userService
.create(user)
.map(
json => {
console.log(json);
if (json.status=='error') {
console.log('error return throw');
return Observable.throw('Credentials mismatch or not existing');
}
const user = json.data as User;
return user;
},
err => {
console.log(err);
}
);
在我的 singUp.component 中,我这样做了:
onSubmit() {
// blahblah
this.si
.signUp(this.credentials.emailAddress, this.credentials.password, this.credentials.zipCode)
.subscribe(
user => {
console.log(user);
console.log(`SignUpComponent.onSubmit() found user.userId ${user.userId}`);
this.router.navigate(['signin']);
},
err => {
this.errorMessage = `*** SignUpComponent: Error while signing up {err}`;
console.error('*** SignUpComponent: Error while signing up', err);
this.resume();
//this.router.navigate(['signup']);
});
this.ngOnChanges();
}
不幸的是,当服务 returns 出错时(使用 Observable.throw()),组件不会触发 err 闭包但用户闭包将 Observable.throw 作为用户参数。
我希望能触发 err 闭包。
我在那里缺少什么?
更新:这是我得到的:
[Log] SigninService.signUp, zipCode=
[Log] {data: null, status: "error", message: "Error user create: - missing id API usage v1b3: Tu…ate\"}↵post: []↵.↵", ws: "v1b3: Tuesday, August 25th 2017 20h20 @ Tanger"}
[Log] error return throw
[Log] ErrorObservable {_isScalar: false, error: "Credentials mismatch or not existing", scheduler: undefined, _subscribe: function, …}
[Log] SignUpComponent.onSubmit() found user.userId undefined
为了避免您遇到的问题,我认为您只需要在没有 return 和 的情况下执行 throw 'Credentials mismatch or not existing'
可观察 部分。在执行可观察对象期间引发的任何错误都将作为错误传播到当前 Observable
.
目前,您只是将 json 响应替换为 Observable
,这不是您想要的。
理想情况下,服务器应该 return 错误响应而不是 json 带有错误消息的响应,后者会触发订阅中的 error
处理程序。
你在用户回调中处理异常,这意味着它已成功执行,在这种情况下 Observable.throws
不会真正充当异常。为了实现这一点,您必须使用必须替换 return Observable.throw("Credentials mismatch or not existing")
的 throw new Error("Credentials mismatch or not existing")
;请看这个:
我最终想出了以下解决方案,扩展了以下事实:1) 使用 throw new Error() 我仍然可以 return Observable 和 2) 当错误抛出时,订阅完成参数不会触发,需要使用 finally() 调用如下:
注册服务:
create(user: User): Observable<User> {
const wsUrl = `${this.wsApi}m=create&id=${user.id}`; // URL to web api
return this.http.post(wsUrl, JSON.stringify(user), { headers: this.headers })
.retry(3)
.map(res => {
const json = res.json() as any;
if (json.status=='error') throw new Error(json.message);
return json.data as User;
});
}
注册组件:
onSubmit() {
// blahblah
this.progressing = true;
this.si
.signUp(this.credentials.emailAddress, this.credentials.password, this.credentials.zipCode)
.finally(() => setTimeout(() => this.progressing = false, 1000))
.subscribe(
user => this.router.navigate(['signin']),
err => this.errorMessage = err
);
this.ngOnChanges();
}