I'm writing a Restify application on Node.js. And I need to have a function that is called when some errors inside Restify callbacks are happening. This function should send a response to a client. If I'm not using Promises or async functions, I can do something like that:
server.on('uncaughtException', (req, res, route, err) => {
log.error(err);
res.send(err);
});
But if my callback is async
function, then the exception inside a function isn't called, and unhandledPromiseRejection
is raised instead.
How can I refactor my code so it would handle unhandled Promise rejections the same way it handles usual errors?
And yes, I know that I can check for errors inside a Restify middleware itself, but still it makes the code more complicated, it's easier to write
if (!core.validateUUID(req.params.deviceId)) {
throw new Error(`Device ${req.params.deviceId} is wrong`)
}
then
if (!core.validateUUID(req.params.deviceId)) {
return next(new restify.InvalidArgumentError({ body: {
success: false,
error: `Device ${req.params.deviceId} is wrong`,
} }));
}
I was struggling with this for a while and I came up with a simple solution. I created a simple wrapper function, that wraps the route handlers/middlewares and runs the code inside a promise. That way, unhandled rejections and uncaught exceptions can be handled is same callback:
// your error general handler
function errorResponse(req, res, err) { ... }
/**
* When using promises inside handler, you need to return the Promise from it to allow proper rejection handling
*
* @param {Function} callback with `req`, `res` and `next` parameters
* @returns {Function}
*/
function catcher(callback) {
return (req, res, next) => {
Promise
.resolve()
.then(() => callback(req, res, next))
.catch(err => errorResponse(req, res, err));
};
}
// use it like this
server.use(catcher(middleware1));
server.post(catcher(postRoute));
server.get(catcher(getRoute));
When using promises inside your handler, you need to return the Promise from it to allow proper rejection handling.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With