Nathaniel's blog
Back to posts

Build a Javascript async function error handler

Nathaniel LinSeptember 12, 20192 min read10 views
Build a Javascript async function error handler

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

 }) )

Share this post

Reactions