rubmz rubmz - 1 month ago 6
TypeScript Question

catching errors in typescript promises

Angular2 has very useful promises error catching mechanism for chained promises. Yet, the usual case (at least for me) is that of promises called from within the resolve handler of the previous one. This is due to the need to process information prior to starting the next promise. For example:

this.d( "facebookOAuthLogin() - starts" );
this.fbProvider.login().then(
( loginResponse: { status: string, authResponse: any, accessToken: string, expiresIn: string, session_key: string, sig: string, userID: string } ) =>
{
this.d( "facebookOAuthLogin() - fbProvider.login() succeeded" );
Config.config.sessionToken = loginResponse.authResponse.accessToken;
this.fbProvider.getCurrentUserProfile().then(
( profileData : { email: string, name: string } ) =>
{
this.d( "facebookOAuthLogin() - fbProvider.getCurrentUserProfile() succeeded" );
Config.config.user_email = profileData.email;
Config.config.user_name = profileData.name;
this.fbProvider.getUserPicture().then(
( pictureData : { data:{ is_silhouette: boolean, url: string, width: number, height: number } } ) =>
{
this.d( "facebookOAuthLogin() - fbProvider.getUserPicture() succeeded" );
// this.facebook_picture_url = pictureData.data.url;
// this.facebook_picture_is_silhouette = pictureData.data.is_silhouette;
if( pictureData.data.is_silhouette || pictureData.data.url == null )
{
this.d( "facebookOAuthLogin() - pictureData.data.url == null" );
Config.config.jpegBase64Data = null;
this.afterFacebookLogin();
}
else
{
this.d( "facebookOAuthLogin() - pictureData.data.url != null" );
ImageStore.readToData( pictureData.data.url ).then(
dataBase64 =>
{
this.d( "facebookOAuthLogin() - facebook picture read successfully" );


So, the question is - If I want to catch all the errors in all the handlers in the simplest way (let's leave out the type of the exceptions - Assume I just need to log the error and report. Any error - Without handling them separatedly.)

From what I understand putting a try{}catch(err) around the code would not catch the errors thrown from the Promise handler.

With the code above - Do I need to add a try/catch in every Promise handler, or can I use the external (first) promise's .catch() method?

Answer

One way to chain promises is to return a promise inside then function, like this:

method1()
  .then(response1 => {
    // ... do something
    return method2(response1);
  })
  .then(response2 => {
    // ... do something
    return method3(response3);
  })
  .catch(error => handleError(error))
  .finally(() => handleFinally())

When all promises are successfully resolved, as expected, all methods are called sequentially (method1 -> method2 -> method3 -> handleFinally).

When one promise fails, all subsequent are skipped and catch is invoked instead. Supposing method2 fails, we have this chain of calls: method1 -> method2 -> handleError -> handleFinally.

Now suppose we want to ignore the error in method2, we can add a catch statement for this call:

method1()
  .then(response1 => {
    // ... do something
    return method2(response1);
  })
  .catch(error2 => silentlyHandleError(error2))
  .then(response2 => {
    // ... do something
    return method3(response3);
  })
  .catch(error => handleError(error))
  .finally(() => handleFinally())

or

method1()
  .then(response1 => {
    // ... do something
    return method2(response1)
      .catch(error2 => silentlyHandleError(error2));
  })
  .then(response2 => {
    // ... do something
    return method3(response3);
  })
  .catch(error => handleError(error))
  .finally(() => handleFinally())
Comments