javascript - Promise Error in Observable not calling catch - Stack Overflow

I am using @angularhttp for http calls (Observable) and NativeStorage library for storage mechanism wh

I am using @angular/http for http calls (Observable) and NativeStorage library for storage mechanism which is Promise. That's why I use FromPromise to convert Promise funtion "NativeStorage.getItem("xxx")" to Observable.

I am even not sure if this is a good practice and the chain is broken at the line "console.log("HIT SUCCESSFULLY");" and stops executing the code.

Since there is no item called "externalAccessToken" in the storage, it is normal to catch the exception null in Promise but I don't understand why it stops executing after that.

Till now, I have tried to return something else other than null and using "Promise.reject()" which caused "Unhandled Promise rejection" error.

How can I keep the the code executing and hit the catch function of Observable

public getExternalAccessTokenFromStorage(): Observable<any> {
    let externalAccessTokenPromise = NativeStorage.getItem('externalAccessToken');
    let getExternalAccessTokenFromStorage: Observable<any> = Observable.fromPromise(externalAccessTokenPromise.then(x => x)
   .catch(() => {
        console.log("HIT SUCCESSFULLY");
        return null
   }));

    return getExternalAccessTokenFromStorage.map(x => {
        console.log("NOT HIT AT ALL");
        return x;
    }).catch(() => {
        console.log("NOT HIT AT ALL");
        return null;
    });
}



public getUserInfo(): Observable<StoredUserModel> {        
    //Get External Access Token From LocalStorage        

    return this.getExternalAccessTokenFromStorage().flatMap((x: IExternalAccessTokenBindingModel) => {
        return this.getAccessTokenFromStorage().flatMap((accessToken: AccessTokenModel) => {
            console.log("NOT HIT AT ALL");
            let headers = new Headers();
            headers.append("Authorization", "Bearer " + accessToken.access_token);
            headers.append("Content-Type", "application/json");
            let options = new RequestOptions({ headers: headers });
            var externalBindingModel = JSON.stringify(x);
            return this.http.post(this.baseUrl + '/api/Account/ExternalUserInfo', externalBindingModel, options).map((res: Response) => {
                //ADD USER INTO NATIVESTORAGE
                this.addUserIntoStorage(res.json());
                return res.json();
            });
        });
    }).catch(x => {
        return this.getAccessTokenFromStorage().flatMap((accessToken: AccessTokenModel) => {
            console.log("NOT HIT AT ALL");
            let headers = new Headers();
            headers.append("Authorization", "Bearer " + accessToken.access_token);
            let options = new RequestOptions({ headers: headers });
            return this.http.get(this.baseUrl + '/api/Account/UserInfo', options).map((res: Response) => {
                //ADD USER INTO NATIVESTORAGE
                let user: StoredUserModel = res.json();
                this.addUserIntoStorage(res.json());
                return user;
            });
        }).catch(error => {
            return null;
        });
    });
}

UPDATED QUESTION:

I have removed Promise.catch and keep Observable.catch in order to catch unhandled exception in Observable;

public getExternalAccessTokenFromStorage(): Observable<any> {
    let externalAccessTokenPromise = NativeStorage.getItem('externalAccessToken');
    let getExternalAccessTokenFromStorage: Observable<any> = Observable.fromPromise(externalAccessTokenPromise);

    return getExternalAccessTokenFromStorage.map(x => {
        return x;
    }).catch(() => {
        return null;
    });
}

And I get the following error;

I am using @angular/http for http calls (Observable) and NativeStorage library for storage mechanism which is Promise. That's why I use FromPromise to convert Promise funtion "NativeStorage.getItem("xxx")" to Observable.

I am even not sure if this is a good practice and the chain is broken at the line "console.log("HIT SUCCESSFULLY");" and stops executing the code.

Since there is no item called "externalAccessToken" in the storage, it is normal to catch the exception null in Promise but I don't understand why it stops executing after that.

Till now, I have tried to return something else other than null and using "Promise.reject()" which caused "Unhandled Promise rejection" error.

How can I keep the the code executing and hit the catch function of Observable

public getExternalAccessTokenFromStorage(): Observable<any> {
    let externalAccessTokenPromise = NativeStorage.getItem('externalAccessToken');
    let getExternalAccessTokenFromStorage: Observable<any> = Observable.fromPromise(externalAccessTokenPromise.then(x => x)
   .catch(() => {
        console.log("HIT SUCCESSFULLY");
        return null
   }));

    return getExternalAccessTokenFromStorage.map(x => {
        console.log("NOT HIT AT ALL");
        return x;
    }).catch(() => {
        console.log("NOT HIT AT ALL");
        return null;
    });
}



public getUserInfo(): Observable<StoredUserModel> {        
    //Get External Access Token From LocalStorage        

    return this.getExternalAccessTokenFromStorage().flatMap((x: IExternalAccessTokenBindingModel) => {
        return this.getAccessTokenFromStorage().flatMap((accessToken: AccessTokenModel) => {
            console.log("NOT HIT AT ALL");
            let headers = new Headers();
            headers.append("Authorization", "Bearer " + accessToken.access_token);
            headers.append("Content-Type", "application/json");
            let options = new RequestOptions({ headers: headers });
            var externalBindingModel = JSON.stringify(x);
            return this.http.post(this.baseUrl + '/api/Account/ExternalUserInfo', externalBindingModel, options).map((res: Response) => {
                //ADD USER INTO NATIVESTORAGE
                this.addUserIntoStorage(res.json());
                return res.json();
            });
        });
    }).catch(x => {
        return this.getAccessTokenFromStorage().flatMap((accessToken: AccessTokenModel) => {
            console.log("NOT HIT AT ALL");
            let headers = new Headers();
            headers.append("Authorization", "Bearer " + accessToken.access_token);
            let options = new RequestOptions({ headers: headers });
            return this.http.get(this.baseUrl + '/api/Account/UserInfo', options).map((res: Response) => {
                //ADD USER INTO NATIVESTORAGE
                let user: StoredUserModel = res.json();
                this.addUserIntoStorage(res.json());
                return user;
            });
        }).catch(error => {
            return null;
        });
    });
}

UPDATED QUESTION:

I have removed Promise.catch and keep Observable.catch in order to catch unhandled exception in Observable;

public getExternalAccessTokenFromStorage(): Observable<any> {
    let externalAccessTokenPromise = NativeStorage.getItem('externalAccessToken');
    let getExternalAccessTokenFromStorage: Observable<any> = Observable.fromPromise(externalAccessTokenPromise);

    return getExternalAccessTokenFromStorage.map(x => {
        return x;
    }).catch(() => {
        return null;
    });
}

And I get the following error;

Share Improve this question edited Jul 29, 2017 at 17:55 P.S. 16.4k14 gold badges65 silver badges86 bronze badges asked Jul 1, 2017 at 16:19 mctunamctuna 8714 gold badges19 silver badges42 bronze badges 7
  • Why not use Observable.catch instead of Promise.catch, i.e. move the error handling out of the fromPromise? – jonrsharpe Commented Jul 1, 2017 at 16:21
  • I have tried that and it throws something like "unhandled error": item null exception. If you want I can produce and write the exact error – mctuna Commented Jul 1, 2017 at 16:23
  • Yes, please give a minimal reproducible example without any extraneous detail. – jonrsharpe Commented Jul 1, 2017 at 16:24
  • @jonrsharpe I have updated the questions – mctuna Commented Jul 1, 2017 at 16:34
  • 2 Note that you need to return an observable from catch callback - learnrxjs.io/operators/error_handling/catch.html – jonrsharpe Commented Jul 1, 2017 at 16:40
 |  Show 2 more ments

2 Answers 2

Reset to default 3

Catch works exactly the same as the try / catch clasues in programming.

Give the following example:

try {
   throw new Error('bang');
} catch(ex) {
   // do nothing
}

console.log('I'm still reachable');

We can reproduce the above with observable like this:

let o = Observable.create((observer)=>{
     observer.error(new Error('bang'));
}).catch(()=>{ 
    // do nothing
});

o.subscribe(()=>{
   console.log('I'm still reachable');
});

If you want to catch and process an error, but then prevent code below from executing using try / catch you would do this:

try {
   throw new Error('bang');
} catch(ex) {
   // do some logic here
   throw ex;
}

console.log('I cannot be reached');

It's the same in observables. You have to re-throw the error or yield an observable that also fails.

let o = Observable.create((observer)=>{
     observer.error(new Error('bang'));
}).catch((ex)=>{ 
    // do some logic here
    return Observable.throw(ex);
});

o.subscribe(()=>{
   console.log('I cannot be reached');
});

The problem is that you're catching, but not handling the error. You will want to throw the error as an Observable.

public getExternalAccessTokenFromStorage(): Observable<any> {
    let externalAccessTokenPromise = NativeStorage.getItem('externalAccessToken');
    let getExternalAccessTokenFromStorage: Observable<any> = Observable.fromPromise(externalAccessTokenPromise);

    return getExternalAccessTokenFromStorage.map(x => {
        return x;
    }).catch((error: any) => 
        Observable.throw(error.json().error || 'Server error');
    );
}

You can then handle your response and error in the form of a promise:

this.getExternalAccessTokenFromStorage().subscribe(
  res => console.log(res),
  error => console.log(error));

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745460847a4628703.html

相关推荐

  • javascript - Promise Error in Observable not calling catch - Stack Overflow

    I am using @angularhttp for http calls (Observable) and NativeStorage library for storage mechanism wh

    4小时前
    20

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信