0

Hi I am trying to customize the error response if a promise from array fails

I have referred to Handling errors in Promise.all and developed the below code I might need to tweak it to get desired response. Need some help

I have following code implemented. Please run to see the out put

//User Data
const usersData = [{
    firstName: 'John',
    lastName: 'Smith',
    isResolved: true //I have this only to reject or resolve the promise
  },
  {
    firstName: 'Phil',
    lastName: 'Doe',
    isResolved: false
  },
  {
    firstName: 'Dan',
    lastName: 'Joe',
    isResolved: true
  }
]

//Promise which gets resolved
const delayResolveFunction = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const id = Math.floor((Math.random() * 10) + 1)
      resolve({
        userid: id,
        isSuccess: true
      })
    }, 100)

  })
}

// Promise which gets rejected
const delayRejectFunction = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const id = Math.floor((Math.random() * 10) + 1)
      reject({
        isSuccess: false
      })
    }, 100)

  })
}

//function which creates users based on whethere userid is present
const createUsers = (users) => {
  const promiseArray = [];
  users.forEach((user) => {
    let userId = user.id;

    if (!userId) {
      if (user.isResolved) {
        promiseArray.push(delayResolveFunction().then((response) => {
          userId = response.userid
          isSuccess = response.isSuccess
          return { ...user,
            userId,
            isSuccess
          }
        }))
      }
      if (!user.isResolved) {
        // statement is not executed because error is thrown
        promiseArray.push(delayRejectFunction().then((response) => {
          userId = response.userId
          return { ...user,
            userId
          }
        }))
      }

    } else return null;



  });
  // I have this logic to access the data even if one promise fails among three
  //If you look at the response object we can see request for second user failed


  // My question is can I also send user object for failed response?
  return Promise.all(promiseArray.map(p => p.catch((err) => {
    return err;
  })))
}


//mainfunction where array of promises are resolved
const mainFunction = async() => {
  try {
    const arrayOfPromises = await createUsers(usersData);
    console.log(arrayOfPromises)
  } catch (err) {
    console.log(err)
  }
}

mainFunction();

I am looking to get output as below

[{
    "firstName": "John",
    "lastName": "Smith",
    "isResolved": true,
    "userId": 3,
    "isSuccess": true
  },
  {
    //for failed response
    "firstName": 'Phil',
    "lastName": 'Doe',
    "isResolved": false,
    "isSuccess": false
  },
  {
    "firstName": "Dan",
    "lastName": "Joe",
    "isResolved": true,
    "userId": 8,
    "isSuccess": true
  }
]

if you like to have a look in codepen here is the link https://codepen.io/punith77/pen/OBdLZa?editors=0012

Please let me know if I can get output as above

georgeawg
  • 48,608
  • 13
  • 72
  • 95
Mahesh
  • 221
  • 1
  • 3
  • 14

2 Answers2

0

Use a catch instead of then after the delayRejectFunction call. And use the error object in the catch to get the isSuccess. I have posted the changes below.

//User Data
const usersData = [{
    firstName: 'John',
    lastName: 'Smith',
    isResolved: true //I have this only to reject or resolve the promise
  },
  {
    firstName: 'Phil',
    lastName: 'Doe',
    isResolved: false
  },
  {
    firstName: 'Dan',
    lastName: 'Joe',
    isResolved: true
  }
]

//Promise which gets resolved
const delayResolveFunction = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const id = Math.floor((Math.random() * 10) + 1)
      resolve({
        userid: id,
        isSuccess: true
      })
    }, 100)

  })
}

// Promise which gets rejected
const delayRejectFunction = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      reject({
        isSuccess: false
      })
    }, 100)

  })
}

//function which creates users based on whethere userid is present
const createUsers = (users) => {
  const promiseArray = [];
  users.forEach((user) => {
    let userId = user.id;

    if (!userId) {
      if (user.isResolved) {
        promiseArray.push(delayResolveFunction().then((response) => {
          userId = response.userid
          isSuccess = response.isSuccess
          return { ...user,
            userId,
            isSuccess
          }
        }))
      }
      if (!user.isResolved) {
        // statement is not executed because error is thrown
        promiseArray.push(delayRejectFunction().catch((errorObj) => {
          var isSuccess = errorObj.isSuccess;
          return { ...user,
            isSuccess
          }
        }))
      }

    } else return null;



  });
  // I have this logic to access the data even if one promise fails among three
  //If you look at the response object we can see request for second user failed


  // My question is can I also send user object for failed response?
  return Promise.all(promiseArray.map(p => p.catch((err) => {
    return err;
  })))
}


//mainfunction where array of promises are resolved
const mainFunction = async() => {
  try {
    const arrayOfPromises = await createUsers(usersData);
    console.log(arrayOfPromises)
  } catch (err) {
    console.log(err)
  }
}

mainFunction();

Hope this helps :)

dRoyson
  • 1,466
  • 3
  • 14
  • 25
0

I'm not really sure where this code is going to be used in your code base but you could make these changes

The delayRejectFunction

// Promise which gets rejected
const delayRejectFunction = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const id = Math.floor((Math.random() * 10) + 1)
      reject({
        userid: id,
        isSuccess: false
      })
    }, 100)

  })
}

The call to the delayRejectFunction

// statement is not executed because error is thrown
promiseArray.push(delayRejectFunction().then((response) => {
  userId = response.userId
  return { ...user,
    userId
  }
}).catch(err => {
  userId = err.userid
  isSuccess = err.isSuccess
  return { ...user,
    userId,
    isSuccess
  }
}));