Sails错误:抛出新错误('在发送后无法设置标头。')

时间:2015-07-03 13:59:11

标签: node.js mongoose sails.js waterline

您好我是Sails的新手,我正在尝试通过禁用水线功能使用Sails连接到Mongoose。在执行POST操作的Sails中执行我的代码时,我遇到了以下问题

/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)

我的代码如下

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;  
  });
}

基本上我的代码只是将数据输入数据库,在此之前执行用户的身份验证部分。一旦我得到DHCP并点击Post I Encounter上面提到的问题。我的数据被存储到数据库中,但风帆正在下降。我的架构如下

// 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
}

我的路线

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

有人可以帮我解决这个问题,为什么我的风帆应用程序会在后期操作中失败吗?

2 个答案:

答案 0 :(得分:7)

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

正如@nfleury所说,当您尝试多次向客户端发送响应(res.*)时会抛出此错误。

让我们找到问题。

乍一看,没问题。每次使用return时都会致电res.json

问题必然更复杂。也许是异步函数的问题?

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

  // Here you call an asynchronous function
  // Let's 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's name it "function 2"
  statuspacket.save(function (err, data) {
    res.json(...);
    return;  
  });
}

正如我们所见,函数1和2都被调用。我假设在调用回调时会出现问题。

功能2回调总是向客户端发送响应。如果验证了一系列条件,则功能1回调发送响应。明白了!

现在。我们如何解决这个问题?

我认为您要做的是等到第一个回调被调用后再继续。你可以这样做:

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

  // ...

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

答案 1 :(得分:-2)

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

通常当您出现此错误时,表示您发送了两次回复...

可能是由此引起的:

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

如果您有错误,它会再次发送json响应...看起来您在这里错过了“其他”...

相关问题