Sails Error: throw new Error ("Unable to set headers after sending them").

Hi I'm new to Sails and I'm trying to connect to Mongoose using Sails by disabling the waterline functionality. While executing my code in Sails for a POST operation, I am facing the following problem.

/Users/febinp/Documents/Tecsol/Taqua/Taqua-loginpacket/node_modules/mongoose/node_modules/mpromise/lib/promise.js:108
 if (this.ended && !this.hasRejectListeners()) throw reason;
                                                  ^
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:335:11)
at ServerResponse.res.setHeader (/usr/local/lib/node_modules/sails/node_modules/express/node_modules/connect/lib/patch.js:133:22)
at ServerResponse.res.set.res.header (/usr/local/lib/node_modules/sails/node_modules/express/lib/response.js:577:10)
at ServerResponse.res.send (/usr/local/lib/node_modules/sails/node_modules/express/lib/response.js:142:12)
at ServerResponse.res.json (/usr/local/lib/node_modules/sails/node_modules/express/lib/response.js:223:15)
at EventEmitter.<anonymous> (/Users/febinp/Documents/Tecsol/Taqua/Taqua-loginpacket/api/controllers/Status-packetController.js:74:17)
at EventEmitter.<anonymous> (/Users/febinp/Documents/Tecsol/Taqua/Taqua-loginpacket/node_modules/mongoose/node_modules/mpromise/lib/promise.js:175:45)
at EventEmitter.emit (events.js:110:17)
at Promise.safeEmit (/Users/febinp/Documents/Tecsol/Taqua/Taqua-loginpacket/node_modules/mongoose/node_modules/mpromise/lib/promise.js:81:21)
at Promise.fulfill (/Users/febinp/Documents/Tecsol/Taqua/Taqua-loginpacket/node_modules/mongoose/node_modules/mpromise/lib/promise.js:94:24)
at Promise.resolve (/Users/febinp/Documents/Tecsol/Taqua/Taqua-loginpacket/node_modules/mongoose/lib/promise.js:113:23)
at model.<anonymous> (/Users/febinp/Documents/Tecsol/Taqua/Taqua-loginpacket/node_modules/mongoose/lib/document.js:1578:39)
at next_ (/Users/febinp/Documents/Tecsol/Taqua/Taqua-loginpacket/node_modules/mongoose/node_modules/hooks-fixed/hooks.js:89:34)
at EventEmitter.fnWrapper (/Users/febinp/Documents/Tecsol/Taqua/Taqua-loginpacket/node_modules/mongoose/node_modules/hooks-fixed/hooks.js:171:15)
at EventEmitter.<anonymous> (/Users/febinp/Documents/Tecsol/Taqua/Taqua-loginpacket/node_modules/mongoose/node_modules/mpromise/lib/promise.js:175:45)
at EventEmitter.emit (events.js:110:17)
at Promise.safeEmit (/Users/febinp/Documents/Tecsol/Taqua/Taqua-loginpacket/node_modules/mongoose/node_modules/mpromise/lib/promise.js:81:21)
at Promise.fulfill (/Users/febinp/Documents/Tecsol/Taqua/Taqua-loginpacket/node_modules/mongoose/node_modules/mpromise/lib/promise.js:94:24)
at p1.then.then.self.isNew (/Users/febinp/Documents/Tecsol/Taqua/Taqua-loginpacket/node_modules/mongoose/lib/model.js:254:27)
at newTickHandler (/Users/febinp/Documents/Tecsol/Taqua/Taqua-loginpacket/node_modules/mongoose/node_modules/mpromise/lib/promise.js:229:18)
at process._tickDomainCallback (node.js:381:11)

      

My code looks like this

CreateStatus: function (req, res) {
  var params = req.body;
  if(params.SerialNo == null) {
    var response = {};
    response.success = "FALSE";
    response.error = "Serial.NO.is.Null";
    res.json(response);
    return(res);
  }
  // For Authenfication purpose Only
  var mongoose = require('mongoose');
  var login = mongoose.model('Login');
  var SerialNo1 = req.body.SerialNo;

  login.find({ "SerialNo": SerialNo1 }, function (err,data) {
    if(err) {
      res.json({
        success: false,
        error: err
      });
      return;      
    } else {
      if(data.length <= 0) {
        res.json({
          success: false,
          error: "User Doesn't Exists"
        });
        return;          
      }  
    }
  });
  // End of Authentification  

  var msg_parts = params.msg_parts;


  // CONVERSION ALGORITHM FROM INTEGER TO BOOLEAN
  if(msg_parts.chargingStatus <= 0)
    msg_parts.chargingStatus = false;
  else
    msg_parts.chargingStatus = true;

  if(msg_parts.alarmInfo <= 0)
    msg_parts.alarmInfo = false;
  else
    msg_parts.alarmInfo = true;

  if(msg_parts.gpsStatus <= 0)
    msg_parts.gpsStatus = false;
  else
    msg_parts.gpsStatus = true;

  msg_parts.SerialNo = params.SerialNo; // Adding the Serial no into the message parts
  // CONVERSION ALGORITHM FROM INTEGER TO BOOLEAN finished

  var statuspacket = db.StatusPacket(msg_parts);
  // For saving into the Database
  statuspacket.save(function (err,data) {
    if(err) {
      res.json({
        success: false,
        exception: err
      });
      return;
    }
    res.json({
      success: true,
      data:data
    });
    return;  
  });
}

      

Basically, my code just enters data into the database and does some of the user authentication before doing that. Once I got to DHCP and hit Publish, I ran into the problem mentioned above. My data is stored in the database, but the sails are dropping. My circuit looks like this

// Serial No of the device.We require an Index on this column
SerialNo: {
  type: String,
  required: true
},
batteryLevel: {
  type: Number,
  min: 0, // battery level will take values from 0 to 6(0,1,2,3,4,5,6)
  max: 6
},
signalLevel: {
  type: Number,
  min: 0, // Signal Level will take values from 0 to 4 (0,1,2,3,4)
  max: 4,
},
chargingStatus: {
  type: Boolean,   
  default: false
},
alarmInfo: {
  type: Boolean,
  default: false
},
gpsStatus: {
  type: Boolean
},
createdAt: {
  type: Date,
  default: Date.now
},
PurgeDataNumber: {
  type:Number
}

      

My routes

'/Status-packet/CreateStatus': 'Status-packetController.CreateStatus',
'/Status-packet/FindStatus': 'Status-packetController.FindStatus'

      

Can anyone help me with this question on why sails app is running in post operation?

+3


source to share


2 answers


Error: Can't set headers after they are sent.

      

As @nfleury said, this error occurs when you try to send a response ( res.*

) multiple times to the client.

Find the problem.

At first glance, there are no problems. You call return

every time you use res.json

.

Then the problem should be more complex. Could there be a problem with the async function?

CreateStatus: function (req, res) {
  // No problem at the beginning
  // ... 

  // Here you call an asynchronous function
  // Let name it "function 1"
  login.find({ "SerialNo": SerialNo1 }, function (err, data) {
    if(...) {
      res.json(...);
      return;      
    }
  });
  // You've called function 1 but the code continues to be executed

  // ...

  // Another async function is called
  // Let name it "function 2"
  statuspacket.save(function (err, data) {
    res.json(...);
    return;  
  });
}

      



As we saw, functions 1 and 2 are called. I am guessing that the problem occurs when the callbacks are called.

Callback function 2 always sends a response to the client. If the sequence of conditions is tested, callback function 1 also sends a response. Got it!

Now. How can we solve this?

I think you want to wait for the first call to be called before continuing. You can do it like this:

login.find({ "SerialNo": SerialNo1 }, function (err, data) {
  // Function 1 has complete
  if(...) {
    res.json(...);
    return;      
  }

  // ...

  statuspacket.save(function (err, data) {
    res.json(...);
    return;  
  });
});

      

+7


source


Error: Can't set headers after they are sent.

      

Usually when you have this error it means that you have submitted a response twice ...

This can be caused by this:



statuspacket.save(function (err,data) {
  if(err) {
    res.json({
      success: false,
      exception: err
    });
    return;
  }
  res.json({
    success: true,
    data: data
  });
  return;  
});

      

If you have error it will send json response again ... looks like 'else' is missing here ...

-2


source







All Articles