Search code examples
javascriptpromiseunhandled-promise-rejection

UnhandledPromiseRejection undefined problem


I hope you can help me. I am developing a functionality that reads a series of data (data is taked from csv file) and checks if it has to put it in a list or not. The problem comes when I start to check the data (through promises) since it gives me an error telling me that the rejected promise has not been captured. You will need to use the following:

//  -npm install email-existence
const emailExistence = require("email-existence");

The code:

function checkEmailExistencePromise(element) {
  return new Promise((resolve, reject) => {
    emailExistence.check(element.email, (error, response) => {
      if (error) {
        reject(error);
        return;
      }
      // If the person has false email the promise will be save (as object) with "Exists" attribute in false.
      if (!response) {
        resolve({
          name: element.name,
          phone: element.phone,
          email: element.email,
          document: element.document,
          weight: element.weight,
          tags: element.tags,
          exists: false,
        });
        return;
      }
      // If the person has valid email the promise will be save (as object) with "Exists" attribute in true.
      resolve({
        name: element.name,
        phone: element.phone,
        email: element.email,
        document: element.document,
        weight: element.weight,
        tags: element.tags,
        exists: true,
      });
    });
  }).catch(() => {
    throw console.error();
  });
}

// I call the function that will write the CSV file with valid email records.
checkEmails();

// This function collects the promises of the "checkEmailExistencePromise" function and dumps them into an array.
async function checkEmails() {
  const promises = sinRepetidos.map((element) =>
    checkEmailExistencePromise(element)
  );

  const values = await Promise.all(promises);

  // Here we go through the promises (which are also objects) and those with the true attribute I put them in a new array that will be printed later.
  values.forEach((element) => {
    if (element.exists === true) {
      checked.push(element);
    }
  });

Solution

  • Because checkEmailExistencePromise() can throw an error (both through the reject() and the throw call), you need to wrap your

    const values = await Promise.all(promises);
    

    call in checkEmails() in a try..catch as well, like so

    let values = null;
    try {
        values = await Promise.all(promises)
    } catch (e) {
        console.error(e) 
    }
    // do something with values, if it's not null
    

    Edit

    As you most likely don't want checkEmailExistencePromise to throw an error, you can replace it with this:

    function checkEmailExistencePromise(element) {
      // NOTE: we're making is so that this promise never rejects - if there's
      // an error in there, we'll assume that the email isn't valid
      return new Promise(resolve => {
        emailExistence.check(element.email, (error, response) => {
          let exists = false;
          if (error) {
            // we can log the error, to make sure we're not doing anything wrong
            // that needs to be fixed - some errors can be legit, though
            console.error(error);
          }
          
          // NOTE: we should probably actually check the response
          if(response) {
            exists = true;
          }
          
          resolve({
            name: element.name,
            phone: element.phone,
            email: element.email,
            document: element.document,
            weight: element.weight,
            tags: element.tags,
            exists
          })
        });
      })
    }
    

    We take any error to mean that the email isn't valid.

    Also, if element only contains those 6 properties (name, phone, email...), then you can simplify the resolve further with something like this:

    resolve(Object.assign({},element,{exists}))
    

    This will make a shallow clone of the object and add the exists property to it