Hi,
First, let's clarify that I'm not opening this to debate. I'm looking for answers, not arguments.
I started an app using Koa since I heard it has better error handling. But, Express 5 is in developement.
Will express 5 have error handling similar to Koa?
I don't want to spent most of my time putting error handlers everywhere.
Also, how good is the async/await support in express?
Thanks
Hi @Extarys , not using Koa day-to-day, I really don't know exactly how Koa's error handling is, so cannot easily comment on "Will express 5 have error handling similar to Koa?" since I don't have a clean understanding of (1) what it is and (2) what your specific idea of it is.
As for "Also, how good is the async/await support in express?", an async function is simply a function that will automatically be wrapped in a Promise by JavaScript, and there is absolutely plans to make Express 5 handle promises being returned by handlers / middleware, so I assume that is "good", though if you could provide some more detail on what exactly defines "good" support, I can probably provide some better answers.
I hope this helps and starts this off on a non-debate footing.
async/await is a new function of javascript .and will be supported on node.js v8
@jonathanong prob has an insightful opinion on this one.
@dougwilson what do you mean by
Express 5 handle promises being returned by handlers / middleware
Can you provide some pseudo-code example about this 馃槄 ?
Not to speak for @dougwilson , but this is the general idea @agauniyal ...
In Koa, the routers already know how to deal with promises and Koa will return status 500 on uncaught exceptions. With express, if you don't wrap your async handler similar to this, express would crash on uncaught exceptions. This is one of the reasons some of us just find Koa more convenient for writing modern async style code.
app.get('/', safeHandler(handler));
function safeHandler(handler) {
return function(req, res) {
handler(req, res).catch(error => res.status(500).send(error.message));
};
}
async function handler(req, res) {
await new Promise((resolve, reject) => reject(new Error('Hang!')));
res.send('Hello, World!');
}
I've just started using async/await in my Express middleware, and have seen the "wrapper" solution as @lvpro offers above for capturing errors globally suggested in a variety of blog posts.
I too am wondering if there is a way to create a plugin for Express, or to handle those errors globally somehow without using the wrapper. Will Express 5 support this out of the box?
@adamreisnz there's been a ton of PRs and issues over the years for this but still nothing AFAIK :(
Instead of reimplementing the error handling, I would highly recommend delegating the error to express using the next function:
function safeHandler(handler) {
- return function(req, res) {
- handler(req, res).catch(error => res.status(500).send(error.message));
+ return function(req, res, next) {
+ handler(req, res).catch(err => next(err));
};
}
This is my implementation;
'use strict';
/**
* Helper middleware to wrap async functions
*/
module.exports = function wrapAsync(fn) {
return function(req, res, next) {
Promise
.resolve(fn(req, res, next))
.catch(error => next(error));
};
};
Wrapping it in a promise resolve fixes the problem where your function does not return a promise, so it's also safe to use this wrapper with non-async functions.
Error handling is delegated to express.
@adamreisnz I would suggest a small change, to also capture if fn is throwing:
module.exports = function wrapAsync(fn) {
return function(req, res, next) {
- Promise
- .resolve(fn(req, res, next))
+ Promise.resolve()
+ .then(() => fn(req, res, next))
.catch(error => next(error));
};
};
Good point, thanks 馃憤
I've also included a warning to make sure you pass in a function. Otherwise, if you accidentally pass in an undefined value (e.g. typo when referencing a middleware), the problem will be rather hard to debug;
'use strict';
/**
* Helper middleware to wrap async functions
*/
module.exports = function wrapAsync(fn) {
if (typeof fn !== 'function') {
throw new Error('Not a function provided for wrapAsync');
}
return function(req, res, next) {
Promise
.resolve()
.then(() => fn(req, res, next))
.catch(error => next(error));
};
};
module.exports = function wrapAsync(fn) {
if (typeof fn !== 'function') {
- throw new Error('Not a function provided for wrapAsync');
+ throw new TypeError('Not a function provided for wrapAsync');
}
return function(req, res, next) {
Promise
.resolve()
.then(() => fn(req, res, next))
.catch(error => next(error));
};
};
You could also throw a TypeError instead of an error
The TypeError object represents an error when a value is not of the expected type.
I'm not sure if there is a purpose to keeping this issue open any more; if you feel otherwise, please let us know and we can re-open!
Most helpful comment
Hi @Extarys , not using Koa day-to-day, I really don't know exactly how Koa's error handling is, so cannot easily comment on "Will express 5 have error handling similar to Koa?" since I don't have a clean understanding of (1) what it is and (2) what your specific idea of it is.
As for "Also, how good is the async/await support in express?", an async function is simply a function that will automatically be wrapped in a Promise by JavaScript, and there is absolutely plans to make Express 5 handle promises being returned by handlers / middleware, so I assume that is "good", though if you could provide some more detail on what exactly defines "good" support, I can probably provide some better answers.
I hope this helps and starts this off on a non-debate footing.