I am creating a REST API with express, folowing the architecture from this article. in a nutshell, a router is calling a controller.
here is an example of a call:
router.get('/', ModelsController.getModels)
This work fine so far, and now, I'm improving error handling with Boom.
I would like to use the wrapper like in this article, but as I don't use TS and as I am unfamiliar with Promises, I'm struggling with it.
Here is the wrapper:
exports.enhanceHandler = async function (handler) {
return async function (req, res, next) {
try {
const result = await handler(req, res);
if (result instanceof Error && Boom.isBoom(result)) {
res.status(result.output.statusCode).send(formatBoomPayload(result));
}
} catch (error) {
// now log errors to your errors reporting software
if (process.env.NODE_ENV !== "production" && (error.stack || error.message)) {
res.status(500).send(error.stack || error.message);
} else {
res.status(500).send(Boom.internal().output.payload);
}
}
next();
}
}
I'm trying to call it in my router, like this:
router.get('/handler', enhanceHandler(ModelsController.getModels))
However, I've got this error:
Error: Route.get() requires a callback function but got a [object Promise]
What could I do ? Do I need to resolve the promise ? modify enhanceHandler so it return a function and not a promise ?
I am creating a REST API with express, folowing the architecture from this article. in a nutshell, a router is calling a controller.
here is an example of a call:
router.get('/', ModelsController.getModels)
This work fine so far, and now, I'm improving error handling with Boom.
I would like to use the wrapper like in this article, but as I don't use TS and as I am unfamiliar with Promises, I'm struggling with it.
Here is the wrapper:
exports.enhanceHandler = async function (handler) {
return async function (req, res, next) {
try {
const result = await handler(req, res);
if (result instanceof Error && Boom.isBoom(result)) {
res.status(result.output.statusCode).send(formatBoomPayload(result));
}
} catch (error) {
// now log errors to your errors reporting software
if (process.env.NODE_ENV !== "production" && (error.stack || error.message)) {
res.status(500).send(error.stack || error.message);
} else {
res.status(500).send(Boom.internal().output.payload);
}
}
next();
}
}
I'm trying to call it in my router, like this:
router.get('/handler', enhanceHandler(ModelsController.getModels))
However, I've got this error:
Error: Route.get() requires a callback function but got a [object Promise]
What could I do ? Do I need to resolve the promise ? modify enhanceHandler so it return a function and not a promise ?
Share Improve this question asked Feb 18, 2019 at 10:55 KepotxKepotx 1,08212 silver badges28 bronze badges 3-
there are conflict using the
async
keyword. If you havenext
parameter you should use all callback – Manuel Spigolon Commented Feb 18, 2019 at 10:58 - I add async as await is only valid in async function. Can you tell me more about how to use all callback please? – Kepotx Commented Feb 18, 2019 at 11:01
-
1
Remove
async
keyword fromexports.enhanceHandler = async function (handler)
– ponury-kostek Commented Feb 18, 2019 at 11:04
3 Answers
Reset to default 4Handler needs to be sync, but the function it returns can remain async.
exports.enhanceHandler = function (handler) { // delete "async" keyword
return async function (req, res, next) {
try {
const result = await handler(req, res);
if (result instanceof Error && Boom.isBoo
..
Every promise object have a .then method that you need to use to get the result out of a promise object, like this:
handler(req, res).then((res) => {
if (res instanceof Error && Boom.isBoom(res)) {
res.status(res.output.statusCode).send(formatBoomPayload(res));
}
});
We can also removes async from the function if we are not using await anymore.
Let's see what's going on. You've called get() and for second parameter you've used enhanceHandler() call. The call of any async function returns Promise. While the get needs a function reference as the second parameter.
So first you have to avoid async keyword on a function which provides the second parameter for get().