Background
If you are a Js developer, you probably have used  async and await, and you love them.
No more callback hell or .then chains. Just like writing a synchronous program.
Util you run into UnhandledPromiseRejectionWarning or Uncaught (in promise) Error
You begin to wrap every piece of code using try.. catch.., but that seems a lot of work.
But I've got good news, you can write a custom async function error handler:
Solution
const asyncHandler = fn => async (...args) => {
  try {
    await fn(...args);
  } catch (err) {
    console.log(err);
  }
};
It takes all types of functions with any number of arguments.
use it like this:
const asyncHandler = fn => async (...args) => {
  try {
    await fn(...args);
  } catch (err) {
    console.log(err);
  }
};
function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}
const yourFunction = async () => {
  await sleep(2000);
  throw 'something wrong';
  return 'success';
}
(async ()=> {
  await yourFunction(); // will cause Uncaught error
  await asyncHandler(yourFunction)(); // will handle the error properly
})();
Return values
Of course when you need the result of the async function, you can:
const asyncHandler = fn => async (...args) => {
  try {
    return await fn(...args);
  } catch (err) {
    console.log(err);
  }
};
function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}
const yourFunction = async () => {
  await sleep(2000);
  // throw 'something wrong';
  return 'success';
}
(async ()=> {
  const result = await asyncHandler(yourFunction)(); //will handle the error properly
  console.log(result); // => 'success'
})();
Custom error handling
if you need some custom error handling, for example, to use it in express.js
you can do simply by adding some of  your custom logic
const asyncHandler = fn => async (...args) => {
  try {
    await fn(...args);
  } catch (err) {
    logger.error(err);
    const resFn = args.find(arg => arg.name === 'res');
    if (resFn) {
      let errors = {
        message: 'Internal Sever Error',
        error: err
      };
      if (err instanceof mongoose.Error.ValidationError) {
        errors = {
          message: 'Mongoose Model Validation Error',
          error: err
        };
      }
      if (err instanceof mongoose.mongo.MongoError) {
        errors = {
          message: 'MongDB Error',
          error: err
        };
      }
      resFn.status(500).json(errors);
    }
  }
};
later you use it in express routers like this:
router.get('/item',
  asyncHandler(async (req, res) => {
    // router logic here
  })
)
              
    
Top comments (2)
Can I pass a custom error object to the asyncHandler from with the '/item' route
Sure, you can throw custom error, and handle it in asyncHandler, just make sure you have a way to identify it.