1

I use an HTTP API that returns app-level error thru a json where status == 'error'.

In my signUp service, I do that:

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

And in my singUp.component, I do that:

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

Unfortunately, when the service returns an error (with the Observable.throw()), the component doesn't trigger the err closure but the user closure passing the Observable.throw as the user parameter.

I wish I had the err closure to be triggered.

What Im missing there?

Update: Here is what I get:

[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
4
  • what is your .map() doing? Commented Aug 26, 2017 at 20:27
  • it looks for the API status in order to make sure the API returns the brand new user (when status=='success'). In case status equals 'error' (stands for user account is not created), I wish I 'to generate an error for the subscriber. Commented Aug 26, 2017 at 20:30
  • is this working? Commented Aug 26, 2017 at 20:31
  • I added the logs in the question Commented Aug 26, 2017 at 20:35

3 Answers 3

1

You are handling the exception inside the user call back, it means it was succesfuly executed, in that case Observable.throws won't really act as an exception. In order to achieve that, you must use throw new Error("Credentials mismatch or not existing") that must replace return Observable.throw("Credentials mismatch or not existing"); Please, look at this: How to throw error from RxJS map operator (angular)

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks @dag to put me on track. Modify your answer to be: throw new Error("Credentials mismatch or not existing"); that must replace return Observable.thow("Credentials mismatch or not existing"); so that I can accept it.
0

In order to avoid the problem you are having, I think you just need to do throw 'Credentials mismatch or not existing' without the return and Observable parts. Any errors raised during the execution of an observable would be propagated as errors on the current Observable.

At the moment, you are just replacing the json response with an Observable which is not what you want.

Ideally, the server should return an error response rather than a json with an error message and that would trigger your error handler in the subscribe.

1 Comment

Nope, that was my first try before trying return Observable.throw() in a desesparate move.
0

I finally came up with the following solution, expanding on the fact that 1) with throw new Error() I can still return an Observable and 2) when error throws the subscribe completion parameter does not trigger, one need to use the finally() call as follows:

signUp service:

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 component:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.