I am creating a REST API with express, folowing are my architecture,a router is calling a controller.but I got this error, please help me
JavaScript
x
2
1
Error: Route.post() requires a callback function but got a [object Promise]
2
/////// EmailLogin.js middleware Handler
JavaScript
1
97
97
1
const { validationResult } = require('express-validator');
2
3
4
let wrapRoute = async (req, res, next) => {
5
try {
6
// run controllers logic
7
await fn(req, res, next)
8
} catch (e) {
9
// if an exception is raised, do not send any response
10
// just continue performing the middleware chain
11
next(e)
12
}
13
}
14
15
16
17
18
const EmailLogin = wrapRoute(async (req, res) => {
19
20
const errors = validationResult(req);
21
if (!errors.isEmpty()) {
22
return res.status(422).json({ errors: errors.array() });
23
24
} else {
25
26
var gtoken = req.body.gtoken;
27
var gSecretKey = env.secret_key;
28
29
if (!gtoken) throw new Error('no token')
30
31
const captchaURL = `https://www.google.com/recaptcha/api/siteverify?secret=${gSecretKey}&response=${gtoken}`
32
33
await axios({
34
url: captchaURL,
35
method: 'POST',
36
headers: {ContentType: 'application/x-www-form-urlencoded'},
37
38
}).then(response => {
39
40
const gVerifyData = response.data
41
if (gVerifyData.success === true) {
42
Users.findOne({'email': req.body.email}).select('+hashPassword +status').exec(function (err, user) {
43
44
if(err){
45
return res.status(500).send({err});
46
} else if (user) {
47
48
validPassword = bcrypt.compareSync(req.body.password, user.hashPassword);
49
50
if (!validPassword){
51
52
return res.send("wrong-info");
53
54
} else if (validPassword && user.status == "active") {
55
56
token = jwt.sign({ id: user._id }, env.jwtsecret,
57
{ expiresIn: "168h" });
58
res.status(200).send({ token: token, user });
59
60
}
61
} else {
62
63
return res.send("wrong-info");
64
65
}
66
}
67
)
68
}else {
69
return res.status(500).send('bot');
70
}
71
}).catch(error => {
72
console.log(error);
73
74
});
75
}
76
});
77
78
79
80
81
82
function errorHandler (err, req, res, next) {
83
console.log(err);
84
// If err has no specified error code, set error code to 'Internal Server Error (500)'
85
if (!err.statusCode) {
86
err.statusCode = 500;
87
}
88
89
res.status(err.statusCode).json({
90
status: false,
91
error: err.message
92
});
93
94
};
95
96
module.exports = {EmailLogin};
97
I’m trying to call it in my router, like this:
/////// Router.js
JavaScript
1
19
19
1
const express = require('express');
2
const router = express.Router();
3
const { check } = require('express-validator');
4
5
const EmailLoginController = require('../controllers/EmailLogin');
6
7
8
var emailLoginValidation = [
9
check('email').notEmpty().trim().escape().isEmail(),
10
check('password').notEmpty().isLength({ min: 7 }).withMessage('password is invalid'),
11
];
12
13
14
15
router.post('/email-login', emailLoginValidation, EmailLoginController.EmailLogin);
16
17
18
module.exports = router;
19
/////// App.js
JavaScript
1
13
13
1
var express = require("express");
2
var app = express();
3
4
5
const Router = require('./routes/Router');
6
app.use('/', Router);
7
8
9
app.listen(3000, function() {
10
console.log('listening on 3000');
11
12
});
13
What could I do ? is it possible to get a Promise Result in the Router as a Handler?
Advertisement
Answer
@turkdev Change your email login function to this
JavaScript
1
60
60
1
const EmailLogin = async (req, res, next) => {
2
3
const errors = validationResult(req);
4
if (!errors.isEmpty()) {
5
return res.status(422).json({ errors: errors.array() });
6
7
} else {
8
9
var gtoken = req.body.gtoken;
10
var gSecretKey = env.secret_key;
11
12
if (!gtoken) throw new Error('no token')
13
14
const captchaURL = `https://www.google.com/recaptcha/api/siteverify?secret=${gSecretKey}&response=${gtoken}`
15
16
await axios({
17
url: captchaURL,
18
method: 'POST',
19
headers: { ContentType: 'application/x-www-form-urlencoded' },
20
21
}).then(response => {
22
23
const gVerifyData = response.data
24
if (gVerifyData.success === true) {
25
Users.findOne({ 'email': req.body.email }).select('+hashPassword +status').exec(function (err, user) {
26
27
if (err) {
28
return res.status(500).send({ err });
29
} else if (user) {
30
31
validPassword = bcrypt.compareSync(req.body.password, user.hashPassword);
32
33
if (!validPassword) {
34
35
return res.send("wrong-info");
36
37
} else if (validPassword && user.status == "active") {
38
39
token = jwt.sign({ id: user._id }, env.jwtsecret,
40
{ expiresIn: "168h" });
41
res.status(200).send({ token: token, user });
42
43
}
44
} else {
45
46
return res.send("wrong-info");
47
48
}
49
}
50
)
51
} else {
52
return res.status(500).send('bot');
53
}
54
}).catch(error => {
55
console.log(error);
56
57
});
58
}
59
};
60
The problem was earlier, you were assigning it to method wrapRoute() which returns a Promise, which was not settled, causing the error which you got.
If that was just for calling next() on error, you could always use it in the catch block.