user3658794
user3658794

Reputation: 769

Why? Error: Can't set headers after they are sent

I keep getting this error: Error: Can't set headers after they are sent.

I have read other posts but I don't understand. I dont have any double callbacks or anything. Where in my code is causing this error?

Error: Can't set headers after they are sent.
    at ServerResponse.OutgoingMessage.setHeader (http.js:689:11)
    at ServerResponse.header (/root/node_modules/express/lib/response.js:666:10)
    at ServerResponse.send (/root/node_modules/express/lib/response.js:146:12)
    at fn (/root/node_modules/express/lib/response.js:900:10)
    at View.exports.renderFile [as engine] (/root/node_modules/jade/lib/jade.js:330:12)
    at View.render (/root/node_modules/express/lib/view.js:93:8)
    at EventEmitter.app.render (/root/node_modules/express/lib/application.js:530:10)
    at ServerResponse.res.render (/root/node_modules/express/lib/response.js:904:7)
    at Query. (/root/tutsplus/server4.js:25:7)
    at Query.emit (events.js:98:17)
var express = require('express'), app = express();
var mysql   = require('mysql');

app.get('/', function(req,res) {

    var connection = mysql.createConnection({
        host: 'localhost',
        user: 'root',
        password: 'xxxx',
        database: 'store'
    });

    var query = connection.query('SELECT * from category');

    query.on('result', function(row) {

        var category = row.category_name;

        res.render('xxxx.jade', {
            category: category
        });
    });

}); // app.get

app.listen(80, function() {

    console.log('we are logged in');
});

Upvotes: 0

Views: 5524

Answers (1)

jfriend00
jfriend00

Reputation: 708056

As I said in my comment, this issue is nearly always caused by improper handling of asynchronous operations which causes pieces of the response to be called out of order.

Per the code example here that uses .on(), you need to end the request only when you get:

query.on('end', function() {
     // all rows have been received
});

I think you are probably calling res.render() more than once because you're calling it in query.on('result', ...) rather than in query.on('end', ....) after all the data has been collected.

The fact that you're doing it in:

query.on('result', ...)

is probably the wrong timing issue causing the problem.


From the mysql nodejs connector documentation, here's an example:

var query = connection.query('SELECT * FROM posts');
query
  .on('error', function(err) {
    // Handle error, an 'end' event will be emitted after this as well
  })
  .on('fields', function(fields) {
    // the field packets for the rows to follow
  })
  .on('result', function(row) {
    // Pausing the connnection is useful if your processing involves I/O
    connection.pause();

    processRow(row, function() {
      connection.resume();
    });
  })
  .on('end', function() {
    // all rows have been received
  });

Upvotes: 3

Related Questions