Back

Build a Javascript async function error handler

Fri, Sep 13 20192 min read
Nathaniel

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
})
)

Comments(0)

Continue with
to comment