Angular 4:如何正确处理应用程序级别的http错误为Observable错误?

时间:2017-08-26 20:17:40

标签: angular observable throw

我使用HTTP API通过json返回应用级错误,其中status ==' error'。

在我的signUp服务中,我这样做:

    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();
    }

不幸的是,当服务返回错误时(使用Observable.throw()),组件不会触发错误闭包,但用户闭包会将Observable.throw作为用户参数传递。

我希望我能够触发错误的关闭。

我在那里失踪了什么?

更新:这是我得到的:

[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

3 个答案:

答案 0 :(得分:1)

您正在处理用户回调中的异常,这意味着它已成功执行,在这种情况下,Observable.throws确实不会成为例外。为实现这一目标,您必须使用必须替换throw new Error("Credentials mismatch or not existing")的{​​{1}};请看一下:How to throw error from RxJS map operator (angular)

答案 1 :(得分:0)

为了避免您遇到的问题,我认为您只需要在没有返回可观察部分的情况下进行throw 'Credentials mismatch or not existing'。在执行observable期间引发的任何错误都将在当前Observable上传播为错误。

目前,您只是用Observable替换json响应,这不是您想要的。

理想情况下,服务器应返回错误响应而不是带有错误消息的json,这将触发订阅中的error处理程序。

答案 2 :(得分:0)

我终于提出了以下解决方案,扩展了以下事实:1)使用throw new Error()我仍然可以返回一个Observable和2)当错误抛出订阅完成参数不触发时,需要使用finally()调用如下:

signUp服务:

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;
    });
}

signUp组件:

    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();
    }