fishamit
fishamit

Reputation: 267

Correct error handling of nested async functions with promise

Let's take this example async function, asyncFunction, which takes a Boolean parameter res. if res is true, the promise will resolve with the string "success". if res is false, the promise will reject with an error object containing the string "success".

const asyncFunction = (res) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (res) return resolve("Success");
      return reject(new Error("Error"));
    }, 1000);
  });
};

I am calling asyncFunction from the function innerFunction when uses a try-catch block. So far so good.

const innerFunction = async () => {
  try {
    return await asyncFunction(false); //Will reject
  } catch (error) {
    console.log("caught error inside innerFunction");
    return error;
  }
};

In outerFunction, I'm executing

const outerFunction = async () => {
  try {
    const result = await innerFunction();
    console.log(result);
  } catch (error) {
    console.log("caught error inside outerFunction");
    console.log(error);
  }
};

Finally, I'm running outer function.

outerFunction();

I expected both catch blocks to catch the error and I was wrong. I guess that you can't catch the same exception twice? I'm not sure but my guess is that the Error object, behind the scenes, gets flagged as a "handled" error and therefore does not get recognized as one in outerFunction. (I would love some insight on this!)

My solution is to throw a new error in innerFunction:

const innerFunction = async () => {
  try {
    return await asyncFunction(false); //Will reject
  } catch (error) {
    console.log("caught error inside innerFunction");
    throw new Error(error);
  }
};

I apologize for the length, but finally, my question is: is this a "correct" way of handling a situation where I must handle the error in outerFunction? Is there any "better" way to do this?

Thank you!

Upvotes: 1

Views: 664

Answers (1)

Kabeer Jaffri
Kabeer Jaffri

Reputation: 708

No you cannot catch same error twice. The method of relaying error will be buggy. instead what I would do is to just forward the outputs and handle them in the outer function.

const innerFunction = async () => asyncFunction(false); // <-- Just return the outputs
const outerFunction = async () => {
  try {
    const result = await innerFunction(); // <-- Error is forwarded and thus handled
  } catch (error) {
    console.log("Caught error inside outerFunction");
  }
};

Upvotes: 1

Related Questions