Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Code still executing after returning res.send

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.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

>Solution :

"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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading