Happydevdays Happydevdays - 1 month ago 6
Node.js Question

node.js app: throw new Error('Can\'t set headers after they are sent.')

I have the following code:

router.get('/:widget', function(req, res, next) {
var widget = req.params.widget;
if ( ! validate(widget) ) {
res.status(400).send("Invalid widget");
return;
}

redis.hget("e:" + widget, 'ccid', function (e, d) {
if (e){
res.status(500).send("Database query failed");
return;
}
if (d) {
res.status(200).send("Resource found");
return;
} else {
res.status(400).send("Unknown widget");
return;
}
});

res.status(200).send("why are you here?");
return;
});


I was under the impression that when the code hits a "return"... it exits the function.
But what seems to be happening is that when the logic hits the:

res.status(400).send("Unknown widget");
return;


path, it still hits the

res.status(200).send("why are you here?");
return;


as well. I thought it would have exited the method.
Clearly, I'm wrong... because I'm getting the above error message. The error goes away when I remove the res.send() and return() after the redis.hget call.

What should I be using instead of the "return" statement after each res.status().send()?

Answer

"redis.hget" is an asynchronous call. As "redis.hget" is an asynchronous call, your "router.get" function keeps on executing to the end, where it encounters "res.status(200).send("why are you here?")" and hence send the response to client. Now, in the next event loop the asynchronous function "redis.hget" gets executed which after getting the response from Redis sever, again call "res.status(400).send...". But as the response was already sent to client before, so you get the error "Can't set headers after they are sent"