I have a function that will return a response res.send()
but after that function is called, the following line of code is till executed.
const db = require('../models');
exports.findAll = (req, res) => {
checkAuthorization(req, res, 'Customer');
db.User.findAll({ include: ['created', 'restaurant'] })
.then((data) => {
res.send({
error: false,
data: data,
message: ['Retrieved successfully.'],
});
})
.catch((err) => {
console.log(err);
res.status(500).send({
error: true,
data: [],
message: err.errors.map((e) => e.message),
});
});
};
Here is the checkAuthorization
function
const checkAuthorization = (req, res, user_type) => {
// Check if user_type param is null
if (user_type == null) return res.status(500).send('`user_type` parameter is required');
// Check if user_type param has valid value
const validuser_type = user_type === 'Customer' || user_type === 'Resto_Admin' || user_type === 'Admin';
// Validate user_type parameter
if (!validuser_type) return res.status(500).send('The value for `user_type` parameter is invalid');
// Check if user is not authorized
if (!(req.user != null && req.user.user_type === user_type))
return res.status(401).send('Oops! You are unauthorized to view your request');
};
Here is the error I get.
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
CodePudding user response:
"Returning from a function" and "returning a response to the user from a web server" are two very different things. The checkAuthorization
function is sending a response, but then doesn't indicate to the calling function that it did that. So the calling function also tries to send a response.
Don't "return" the call to res.status
from checkAuthorization
. If it needs to send a response, it can do so but should also return from the function some indication that it did this. Something as simple as a boolean value can work. For example:
const checkAuthorization = (req, res, user_type) => {
// Check if user_type param is null
if (user_type == null) {
res.status(500).send('`user_type` parameter is required');
return false;
}
// and so on for the other responses...
// then, if no condition produced an HTTP response...
return true;
}
And then when invoking that function:
exports.findAll = (req, res) => {
if (!checkAuthorization(req, res, 'Customer')) {
// the function internally sent a response, stop processing
return;
}
db.User.findAll({ include: ['created', 'restaurant'] })
//...
};
As an aside... This overall logic structure can get confusing fast. What you probably want to do is move your checkAuthorization
logic into its own middleware that would be invoked on every request, before the request even reaches the findAll
logic in this case.
In the middleware pipeline you can use res
to send a response to the user and then end processing, or invoke next
to continue processing.