2

I receive always the error "Error: Can't set headers after they are sent." when calling "res.writeHead(...)" in the very first callback of connect:

var http = require('http');
var connect = require('connect');

var simpleApp = connect();

simpleApp
    .use(function(req, res, next){

        res.writeHead(200, { 'content-type': 'text/html' });
        res.write('response powered by SIMPLE connect-object as middelware');

        console.log('Pre');
        next();
        console.log('Post');
    })
    .use(function(req, res, next){
        console.log('I am the header guy!');
        next();
    })
    .use('/admin', function(req, res, next){
        console.log('someone entered the admin area....');
        next();
    })
    .use(function(req, res){
        console.log('reached the tail of the "chain of responsibility!!!');
        res.end();
    });

http.createServer(simpleApp).listen(process.env.PORT || 3000);

console.log('Running on port "' + (process.env.PORT || 3000) + '"');

// just a save-guard to stop the process after some time...
setTimeout(function(){
    process.exit(0);
}, 20000);

And this is the error message:

Error: Can't set headers after they are sent.
    at ServerResponse.OutgoingMessage.setHeader (http.js:691:11)
    at ServerResponse.res.setHeader (C:\Users\drt\SkyDrive\Programmierung\nodejs\silkveil\node_modules\connect\lib\patch.js:63:22)
    at next (C:\Users\drt\SkyDrive\Programmierung\nodejs\silkveil\node_modules\connect\lib\proto.js:156:13)
    at Object.handle (C:\Users\drt\SkyDrive\Programmierung\nodejs\silkveil\connectSampleApp.js:13:3)
    at next (C:\Users\drt\SkyDrive\Programmierung\nodejs\silkveil\node_modules\connect\lib\proto.js:193:15)
    at Function.app.handle (C:\Users\drt\SkyDrive\Programmierung\nodejs\silkveil\node_modules\connect\lib\proto.js:201:3)
    at Server.app (C:\Users\drt\SkyDrive\Programmierung\nodejs\silkveil\node_modules\connect\lib\connect.js:65:37)
    at Server.EventEmitter.emit (events.js:98:17)
    at HTTPParser.parser.onIncoming (http.js:2108:12)

When I move the "writeHead"-code into the very last callback everything is fine:

.use(function(req, res){
        console.log('reached the tail of the "chain of responsibility!!!');
        res.writeHead(200, { 'content-type': 'text/html' });
        res.write('response powered by SIMPLE connect-object as middelware');
        res.end();
    });

So my question is: Is it only permitted to use writeHead/write in the very last callback when using Connect?

rgettman
  • 176,041
  • 30
  • 275
  • 357
thuld
  • 680
  • 3
  • 10
  • 29

2 Answers2

3

check the other question. res.writeHead Basically after res.writeHead is called, the header could not be modified any more, while next method would try to modify the header which will cause the exception.

So you can modify the header in the first connect callback, but you are not allowed to write the body(res.write). Following code should work correctly. In short, you can modify the header but not to flush them.

var http = require('http');
var connect = require('connect');

var simpleApp = connect();

simpleApp
    .use(function(req, res, next){
        res.statusCode = 200;
        res.setHeader( 'content-type', 'text/html' );

        console.log('Pre');
        next();
        console.log('Post');
    })
    .use(function(req, res, next){
        console.log('I am the header guy!');
        next();
    })
    .use('/admin', function(req, res, next){
        console.log('someone entered the admin area....');
        next();
    })
    .use(function(req, res){
        res.write('response powered by SIMPLE connect-object as middelware');
        console.log('reached the tail of the "chain of responsibility!!!');
        res.end();
    });

http.createServer(simpleApp).listen(process.env.PORT || 3000);

console.log('Running on port "' + (process.env.PORT || 3000) + '"');

// just a save-guard to stop the process after some time...
setTimeout(function(){
    process.exit(0);
}, 20000);
Community
  • 1
  • 1
Changgeng
  • 578
  • 2
  • 8
  • Ok, so it is only "permitted" to call "res.write" in the very last callback!? Because I am able the use "res.setHeader('content-type', 'text/html');" in the very first callback and it is working. – thuld Nov 14 '13 at 15:25
  • Right, you must leave the response in Head part before the very last callback. – Changgeng Nov 14 '13 at 15:26
0

You forgot this line in your first part of code:

res.end();

If that isn't working there is comment from TJ Holowaychuk here: https://github.com/senchalabs/connect/issues/683#issuecomment-10018892

Andrew Surzhynskyi
  • 2,726
  • 1
  • 22
  • 32
  • The "res.end()" is called in the very last connect-callback. My idea is that i write in the response in differnt callbacks and then end the response in the very last callback and I do not understand the comment in your link... why is it not a good idea to use "writeHead"? I am quite new to node.js so bear with me – thuld Nov 14 '13 at 15:04