Monday, June 3, 2024
 Popular · Latest · Hot · Upcoming
163
rated 0 times [  166] [ 3]  / answers: 1 / hits: 22639  / 8 Years ago, thu, september 1, 2016, 12:00:00

Starting off with a basic node app, and I can't figure out how to beat this write after end error, even with the callbacks suggested on several sites.



index.js:



var server = require(./server);
var router = require(./router);
var requestHandlers = require(./requestHandlers);

var handle = {}
handle[/] = requestHandlers.start;
handle[/start] = requestHandlers.start;
handle[/upload] = requestHandlers.upload;

server.start(router.route, handle);


server.js:



var http = require(http);
var url = require(url);

function start(route, handle) {
function onRequest(request, response) {
var postData =;
var pathname = url.parse(request.url).pathname;
console.log(Request for + pathname + received.);

route(handle, pathname, response);
}

http.createServer(onRequest).listen(8888);
console.log(Server has started.);
}

exports.start = start;


router.js:



function route(handle, pathname, response) {
console.log(About to route a request for + pathname);
if (typeof handle[pathname] === 'function') {
handle[pathname](response);
}
else {
console.log(No request handler found for + pathname);
response.writeHead(404, {Content-Type: text/plain});
response.write(404 Not found);
response.end();
}
}

exports.route = route;

and now the culprit, requestHandlers.js:

function start(response) {
console.log(Request handler 'start' was called.);

var body = '<html>'+
'<head>'+
'<meta http-equiv=Content-Type content=text/html; '+
'charset=UTF-8 />'+
'</head>'+
'<body>'+
'<div>Hello Start</div>' +
'</body>'+
'</html>';

response.writeHead(200, {Content-Type: text/html});
response.write(body);
response.end();
}

function upload(response) {
console.log(Request handler 'upload' was called);
response.writeHead(200, {Content-Type: text/plain});
response.write(Hello Upload);
response.end();
}

exports.start = start;
exports.upload = upload;


And here's the stack trace:




C02RF8L7FVH5:HelloWorld francop$ node index.js
Server has started.
Request for / received.
About to route a request for /
Request handler 'start' was called.
About to route a request for /
Request handler 'start' was called.
events.js:141
throw er; // Unhandled 'error' event
^



Error: write after end
at ServerResponse.OutgoingMessage.write (_http_outgoing.js:430:15)
at Object.start (/Users/francop/Documents/Apps/HelloWorld/requestHandlers.js:18:14)
at route (/Users/francop/Documents/Apps/HelloWorld/router.js:5:21)
at IncomingMessage. (/Users/francop/Documents/Apps/HelloWorld/server.js:19:6)
at emitNone (events.js:67:13)
at IncomingMessage.emit (events.js:166:7)
at endReadableNT (_stream_readable.js:921:12)
at nextTickCallbackWith2Args (node.js:442:9)
at process._tickCallback (node.js:356:17)




The only answers I found anywhere were It's async so use a callback like so:



response.write(body, function(err) {
response.end();
});


...Which throws the exact same error.



Any help with this would be amazing. The few sparse answers I've found online don't help at all.



Thanks!


More From » node.js

 Answers
12

Return your body in response.end() instead of response.write()



function start (response) {
console.log(Request handler 'start' was called.);
var body = '<html>'+
'<head>'+
'<meta http-equiv=Content-Type content=text/html; '+
'charset=UTF-8 />'+
'</head>'+
'<body>'+
'<div>Hello Start</div>' +
'</body>'+
'</html>';

response.writeHead(200, {Content-Type: text/html});
response.end(body);
}


Edit 1:



The first time response.write() is called, it will send the buffered header information and the first body to the client. The second time response.write() is called, Node.js assumes you're going to be streaming data, and sends that separately. That is, the response is buffered up to the first chunk of body.



So, if you want to send only one chunk, you must use response.end(body), and if you want to send multiple chunks you must end you called with the response.end() after multiple response.write().



Example single chunk:



function (chunk){
response.end(chunk);
}


Example multiple chunks:



function (chunkArray){
// loop on chunks
for(var i=0; i < chunkArray.length; i++){
response.write(chunkArray[i]);
}

// end the response with empty params
response.end();
}

[#60851] Tuesday, August 30, 2016, 8 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
simone

Total Points: 558
Total Questions: 96
Total Answers: 99

Location: British Indian Ocean Territory
Member since Tue, Feb 22, 2022
2 Years ago
;