Reputation: 1031
I have the below code where I am trying to validate a user with its credentials from Mongo DB :
{
validate: async function (email, password, res) {
console.log('Inside validate method');
try {
var dbUserObj = await User.findOne({ email: email }, (err, user) => {
console.log('Inside validate method111111');
if (err) {
return res.status(500).send('Error on the server.');
}
console.log('Inside validate method 22222');
if (!user) {
return res.status(404).send('No user found.');
}
console.log('Inside validate method33333');
var passwordIsValid = bcrypt.compareSync(password, user.password);
console.log('Is Valid Password :: ' + passwordIsValid);
if (!passwordIsValid) {
return res.status(401).send({
auth: false,
token: null
});
}
});
} catch (e) {
}
console.log('DDDDBBBB USSSERRRR :::' + dbUserObj);
return dbUserObj;
}
}
The below code calls the validate method :
var auth = {
login: function(req, res,next) {
console.log('Inside login');
var email = req.body.email || '';
var password=req.body.password || '';
console.log('Before validate user');
// Fire a query to your DB and check if the credentials are valid
var dbUserObj = auth.validate(email,password,res);
if (!dbUserObj) { // If authentication fails, we send a 401 back
res.status(401);
res.json({
"status": 401,
"message": "Invalid credentials"
});
return;
}
if (dbUserObj) {
res.send(genToken(dbUserObj));
}
}
Whenever there is a condition when the password is incorrect i am getting the error :
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
Cannot really figure out the issue.
Upvotes: 0
Views: 6338
Reputation: 51846
The route that calls your validate()
needs to accept the next
callback parameter from express, otherwise the framework assumes that when the asynchronous function returns (which occurs at the first await
expression), it has completed all its work and at that point it continues down its routes to the default error handling which sends a 404 before your database query resumes async control flow in validate
.
When your route handler accepts the next
parameter, it indicates to express that the route will handle asynchronously, and you can do 1 of 3 things:
next()
if you already send a response (which you always do in this case).next()
with no arguments if you don't send a response and want to delegate the response handling to the remaining routes.next(error)
if you want to delegate the response handling to remaining middleware which will handle the error reporting and response for you.Upvotes: 2