Error Handling in 'async-await'

·

2 min read

Problem

In an async function, there can be many Promise instances. In this situation, if a former one throws an error, then the latter one is not called. Below is the example.

function returnNumber(num) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (num > 0) {
        resolve(num);
      } else {
        reject('The number should be positive!');
      }
    }, 1000);
  });
}

async function fn() {
  const result1 = await returnNumber(-1);
  console.log(result1);
  // This part is not called.
  const result2 = await returnNumber(1);
  console.log(result2);
}

fn().catch(console.log);
// The number should be positive!

To solve this, there should be error-handling codes to each Promise instance.

From now on, let me show you how to do that.

Solution 1: Using 'try-catch'

function returnNumber(num) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (num > 0) {
        resolve(num);
      } else {
        reject('The number should be positive!');
      }
    }, 1000);
  });
}

async function fn() {
  try {
    const result = await returnNumber(-1);
    console.log(result);
  } catch (error) {
    console.log(error);
  }

  try {
    const result = await returnNumber(1);
    console.log(result);
  } catch (error) {
    console.log(error);
  }
}

fn();
// The number should be positive!
// 1

Not to repeat 'try-catch', a wrapper function can be used.

function returnNumber(num) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (num > 0) {
        resolve(num);
      } else {
        reject('The number should be positive!');
      }
    }, 1000);
  });
}

async function wrap(runningFunction, value) {
  try {
    return await runningFunction(value);
  } catch (error) {
    return error;
  }
}

async function fn() {
  const result1 = await wrap(returnNumber, -1);
  console.log(result1);
  const result2 = await wrap(returnNumber, 1);
  console.log(result2);
}

fn();
// The number should be positive!
// 1

Solution 2: Attaching 'catch' Method after Each Promise Instance

function returnNumber(num) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (num > 0) {
        resolve(num);
      } else {
        reject('The number should be positive!');
      }
    }, 1000);
  });
}

async function fn() {
  const result1 = await returnNumber(-1).catch(console.log);
  console.log(result1);
  const result2 = await returnNumber(1).catch(console.log);
  console.log(result2);
}

fn();
// The number should be positive!
// undefined
// 1