Thursday, 16 March 2017

Promise then and catch clauses not working

Background

I have a multitude of functions that may or may not return a Promise and that may or may not fail, like in the examples below:

let goodFun = (fruit) => `I like ${fruit}`;

let badFun = (fruit) => {
    throw `${fruit} is spoiled!`;
};

let badPromise = (fruit) => Promise.resolve().then(() => {
    throw `Promise failed with ${fruit}`;
});

let goodPromise = (fruit) => Promise.resolve().then(() => {
    return `Promise succeeded with ${fruit}`;
});

Because each function may or may not return a promise, which may or may not fail, I modified executeSafe from another StackOverflow post, that takes a function and its arguments as parameters, and then Promisifies the function and its result:

let executeSafe =
    (fun, ...args) => Promise.resolve().then(() => {
        return fun(...args);
    });

My objective with all of this, is to have an asyncFun function that waits for the execution of a batch of functions that were Promisified and then returns whatever came from executing them:

let asyncFun = 
(fruit) => 
    Promise.all([badFun, goodFun, badPromise, goodPromise].map(
        fun => executeSafe(fun, fruit)
    )
);

Problem

asyncFun is designed to run the multitude of functions previously described and some of them I actually expect to see fail. To accommodate for this my asyncFun function has a catch clause. This clause only works with badFun and doesn't work with badPromise. The then clause never works.

let executor = () => {
    let fruitsArr = ["banana", "orange", "apple"];
    let results = [];

    for (let fruit of fruitsArr)
        results.push(
            asyncFun(fruit)
            .then(res => {
                console.log(res);
            })
            .catch(error => {
                console.log(`Error: ${error}`);
            })
        );

    return Promise.all(results);
};

Not even placing the catch clause in the executor's call catches anything else other than the badFun errors.

executor()
    .catch(error => console.log("Failed miserably to catch error!"));

Code

let goodFun = (fruit) => {
  return `I like ${fruit}`;
};

let badFun = (fruit) => {
  throw `${fruit} is spoiled!`;
};

let badPromise = (fruit) => Promise.resolve().then(() => {
  throw `Promise failed with ${fruit}`;
});

let goodPromise = (fruit) => Promise.resolve().then(() => {
  return `Promise succeded with ${fruit}`;
});

let executeSafe =
  (fun, ...args) => Promise.resolve().then(() => {
    return fun(...args);
  });

let asyncFun = (fruit) => Promise.all([badFun, goodFun, badPromise, goodPromise].map(fun => executeSafe(fun, fruit)));

let executor = () => {
  let fruitsArr = ["banana", "orange", "apple"];
  let results = [];

  for (let fruit of fruitsArr)
    results.push(
      asyncFun(fruit)
      .then(res => {
        console.log(res);
      })
      .catch(error => {
        console.log(`Error: ${error}`);
      })
    );

  return Promise.all(results);
};

executor()
  .catch(error => console.log("Failed miserably to catch error!"));

Question:

  • How to fix my code so that its then and catch clauses in asyncFun work as intended?


via Flame_Phoenix

No comments:

Post a Comment