i have this simple middleware that is generating the problem, usually i get this error when i try to send a response after a response was already sent ..but here this is not the case and i can't understand why is this happening.. my code works as follows: use a middleware to extract the current user from a jwt cookie and store it in res.locals variable, if no user exists then null would be stored, then move to next which is the main controller, from there i make a db query and try to send it as response and that's where the error happens..i can confirm that the issue originates in the extraction middleware as the controller worked fine when i removed the mw function..this is my code
middleware
function extractUser(req, res, next) {
let token = req.cookies.userToken;
if (!token) {
res.locals.user = null;
next();
}
try {
let { id } = jwt.verify(token, SERVER_SECRET);
if (id) {
User.findById(id).then(user => {
res.locals.user = user;
next();
})
} else {
res.locals.user = null;
next();
}
} catch (err) {
res.locals.user = null;
next();
}
}
controller
router.get("/:id", extractUser, (req, res) => {
let productId = req.params.id;
Product.findByIdAndUpdate(productId, { $inc: { views: 1 } }, { new: true })
.populate("thing", "thing thing thing thing -_id")
.populate({ path: "thing", populate: { path: "thing", select: "thing thing thing thing thing -_id" } })
.exec().then(product => {
console.log(product);
res.status(200).json({ product });
}).catch(err => {
console.log(err);
res.sendStatus(400);
})
})
CodePudding user response:
Can you please try once with the following code in your controller?
router.get("/:id", extractUser, async (req, res) => {
try{
let productId = req.params.id;
const product = await Product.findByIdAndUpdate(productId, { $inc: { views: 1 } }, { new: true })
.populate("thing", "thing thing thing thing -_id")
.populate({ path: "thing", populate: { path: "thing", select: "thing thing thing thing thing -_id" } });
return res.status(200).json({ product });
}catch (err) {
console.log(err);
return res.sendStatus(400);
}
})
CodePudding user response:
as stated in the question i found that issue originated in the user extraction middleware..after some research i found that next() function wouldn't break/return control from its function and that i was calling next multiple times which would break everything..as a solution make sure next() would be called only once or just use return next() to return from the function.
fixed MW code
function extractUser(req, res, next) {
let token = req.cookies.userToken;
if (!token) {
res.locals.user = null;
next();
}else{
try {
let { id } = jwt.verify(token, SERVER_SECRET);
if (id) {
User.findById(id).then(user => {
res.locals.user = user;
next();
})
} else {
res.locals.user = null;
next();
}
} catch (err) {
res.locals.user = null;
next();
}
}
}