0

I am trying to stream the response from express using res.write method. Below is my code, I am getting "Cannot set headers after they are sent to the client" error when I hit the server. I am trying to stream each entry of the array. Can someone please help?

var express = require('express');
var router = express.Router();

/* GET users listing. */
router.get('/', function(req, res, next) {
  const arr = new Array(1, 2, 3, 4, 5);
  res.writeHead(200, {
    'Content-Type': 'text/plain'
  });

  for(const num of arr) {
    res.write(num);
  }

  res.end('Done!!')
});

module.exports = router;
yondu_udanta
  • 797
  • 1
  • 6
  • 13
  • It seems unlikely that this code, all by itself, exhibits the error you report. I'm thinking there must be some other code involved in creating that specific error. – jfriend00 Jul 29 '19 at 22:15
  • 1
    I do note that [`res.write()`](https://nodejs.org/api/http.html#http_response_write_chunk_encoding_callback) expects a String or Buffer, not a Number, but that's probably not what is causing the error you asked about. – jfriend00 Jul 29 '19 at 22:19
  • Omg!! After converting int to String, it's working!! – yondu_udanta Jul 29 '19 at 22:23

1 Answers1

1

Per the doc, res.write() expects a String or Buffer, not a Number.

And, it looks like this is the spot in the http.write() code where it throws an exception if it's not a String or a Buffer.

  if (!fromEnd && typeof chunk !== 'string' && !(chunk instanceof Buffer)) {
    throw new ERR_INVALID_ARG_TYPE('first argument',
                                   ['string', 'Buffer'], chunk);
  }

It is not clear to me why that error alone would cause the specific error you reported, but it definitely needs to be fixed in order to work properly.

Perhaps the router is catching the exception and trying to set a 500 status? I don't know about that one. Anyway, glad this fixed the problem.


In looking at the Express code more, it does look like there's a try/catch around a request handler here:

Layer.prototype.handle_request = function handle(req, res, next) {
  var fn = this.handle;

  if (fn.length > 3) {
    // not a standard request handler
    return next();
  }

  try {
    fn(req, res, next);
  } catch (err) {
    next(err);
  }
};

This would attempt to turn the above exception into an error response, but if headers were already flushed which they probably would have been when you called res.write(), then this would cause the error you experienced about headers already sent.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • @latish - I added more to my answer and think I can explain why this caused the error you saw. – jfriend00 Jul 29 '19 at 22:38
  • perfect!! that's what is happening exactly. I commented out the code in error handler which is setting the response code to 500 and the error is gone. Thanks a lot mate! – yondu_udanta Jul 30 '19 at 11:38