node reciving an unhandled error event need some insite? - node.js

I've searched Hi and Low through web sites and docs, and I've yet to figure out why Im getting this error. Yes I'm new to node. I thought id ask here as a last resort.
the error I'm receiving is:
events.js:292
throw er; // Unhandled 'error' event
^
Error [ERR_STREAM_WRITE_AFTER_END]: write after end
at writeAfterEnd (_http_outgoing.js:668:15)
at ServerResponse.end (_http_outgoing.js:789:7)
at Server.<anonymous> (/mnt/sdc/opt/codeWork/ReactBuilds/be_full-stack/app.js:10:9)
at Server.emit (events.js:315:20)
at parserOnIncoming (_http_server.js:874:12)
at HTTPParser.parserOnHeadersComplete (_http_common.js:126:17)
Emitted 'error' event on ServerResponse instance at:
at writeAfterEndNT (_http_outgoing.js:727:7)
at processTicksAndRejections (internal/process/task_queues.js:81:21) {
code: 'ERR_STREAM_WRITE_AFTER_END'
}
Here's my code I'm running node v14.16.0
const http = require('http')
const server = http.createServer((req, res)=>{
if(req.url === '/') {
res.end('Welcome to our home page')
}
if(req.url === '/about') {
res.end('Here is our short history')
}
res.end(`
<h1>Ooops</h1>
<p>This is not the page you are looking for</p>
backHome
`)
})
server.listen(5000)
any incites are very welcome
Thanks

You should introduce early returns in your code so that you don't call res.end multiple times when one of the conditions evaluates to true with your request handler still handling 404:
const server = http.createServer((req, res) => {
if (req.url === "/") {
return res.end("Welcome to our home page");
}
if (req.url === "/about") {
return res.end("Here is our short history");
}
res.end(`
<h1>Ooops</h1>
<p>This is not the page you are looking for</p>
backHome
`);
});

Related

Unable to gracefully close http2 client stream in nodejs

I have the following code which has been heavily inspired from nodejs official documentation of a client-side example
import http2 from 'http2';
// The `http2.connect` method creates a new session with example.com
const session = http2.connect('https://somedomain.com');
// Handle errors
session.on('error', (err) => console.error(err))
const req = session.request({
':authority': 'somedomain.com',
':path': '/some-path',
':method': 'GET',
':scheme': 'https',
'accept': 'text/html',
});
// To fetch the response body, we set the encoding
// we want and initialize an empty data string
req.setEncoding('utf8')
let data = ''
// append response data to the data string every time
// we receive new data chunks in the response
req.on('data', (chunk) => { data += chunk })
// Once the response is finished, log the entire data
// that we received
req.on('end', () => {
console.log(`\n${data}`)
session.close();
});
req.on('error', (error) => {
console.log(error);
});
req.end();
Please note that the actual hostname has been replaced with somedomain.com. Running this, results in data getting logged, as expected, however, the process doesn't shut down gracefully. I get the following unhandled error in the terminal.
node:events:504
throw er; // Unhandled 'error' event
^
Error [ERR_HTTP2_STREAM_ERROR]: Stream closed with error code NGHTTP2_FLOW_CONTROL_ERROR
at new NodeError (node:internal/errors:371:5)
at ClientHttp2Stream._destroy (node:internal/http2/core:2330:13)
at _destroy (node:internal/streams/destroy:102:25)
at ClientHttp2Stream.destroy (node:internal/streams/destroy:64:5)
at Http2Stream.onStreamClose (node:internal/http2/core:544:12)
Emitted 'error' event on ClientHttp2Stream instance at:
at emitErrorNT (node:internal/streams/destroy:157:8)
at emitErrorCloseNT (node:internal/streams/destroy:122:3)
at processTicksAndRejections (node:internal/process/task_queues:83:21) {
code: 'ERR_HTTP2_STREAM_ERROR'
}
I understand it is possible that the server is behaving incorrectly. However, there should be a way on the nodejs client to close the session gracefully. Regardless, what would be the ideal way to handle such errors? I've already tried listening to session.on('error') and req.on('error') but that doesn't work.

NodeJS -> Error: write after end (only after first request)

In my express app i have the route below:
router.get('/generatedData', function (req, res) {
res.setHeader('Connection' , 'Transfer-Encoding');
res.setHeader('Content-Type' , 'text/html; charset=utf-8');
res.setHeader('Transfer-Encoding' , 'chunked');
var Client = someModule.client;
var client = Client();
client.on('start', function() {
console.log('start');
});
client.on('data', function(str) {
console.log('data');
res.write(str);
});
client.on('end', function(msg) {
client.stop();
res.end();
});
client.on('err', function(err) {
client.stop();
res.end(err);
});
client.on('end', function() {
console.log('end');
});
client.start();
});
On first call everything works fine (console)
We've got ourselves a convoy on port 3000
start
data
data
data
data
data
...
data
end
GET /generatedData 200 208.426 ms - -
I get all the data and res.end() is being called and successfully closes the request.
The problem starts after first request. I make the exact same request (new one of course) and i get the following error (console):
start
data
data
data
events.js:160
throw er; // Unhandled 'error' event
^
Error: write after end
at ServerResponse.OutgoingMessage.write (_http_outgoing.js:439:15)
at Client.<anonymous> (/Users/xxxx/projects/xxxx/routes/index.js:33:17)
at emitOne (events.js:96:13)
at Client.emit (events.js:188:7)
at FSWatcher.<anonymous> (/Users/xxxx/projects/xxxx/lib/someModule.js:116:32)
at emitTwo (events.js:106:13)
at FSWatcher.emit (events.js:191:7)
at FSEvent.FSWatcher._handle.onchange (fs.js:1412:12)
[nodemon] app crashed - waiting for file changes before starting...
This happens without res.end() being called.
I manage to get some data before the crash.
How can i get this error without res.end() being called at all?
Do i somehow save the previous res instance?
Thanks,
Asaf
Have the same problem. My module was extened by EventEmitter and each time i catch event in router - it stays there, end on second call there are two eventlisteners not one. Setting "once" instead of "on" - worked for me.
client.once('start', function() {
console.log('start');
});
instead of
client.on('start', function() {
console.log('start');
});

Alternative to waiting for child_process to quit node.js

I've got these 2 codes running in 1 script:
The ping script:
app.get("/ping", function(req, res) {
res.send("Pong!");
});
And a work in progress youtube downloader:
app.post("/nodedl", function(req, res) {
res.write("===Gradyncore listnener===\n")
res.write("Recived POST request from "+req.ip+" to /nodedl\n")
res.write("POST(url): "+req.body.url+"\n")
res.write("checking key...\n")
if (req.body.key==="<Insert key here>"){
res.write("Key is valid! Skipping pre-download script...\n")
} else {
res.write("Key is invalid. Running pre-download script...\n")
exec("/home/gradyn/website/projects/nodeDL/scripts/check.sh", function (error, results) {
if (results != null) {
res.write(results+"\n");
} else if (error != null) {
res.write("Error: " + error+"\n");
}
});
}
res.end();
});
The problem is, by the time check.sh finishes, res.end(); has allredy been emitted, causing this error followed by a crash
events.js:160
throw er; // Unhandled 'error' event
^
Error: write after end
at ServerResponse.OutgoingMessage.write (_http_outgoing.js:439:15)
at /home/gradyn/listener/app.js:29:13
at ChildProcess.exithandler (child_process.js:213:5)
at emitTwo (events.js:106:13)
at ChildProcess.emit (events.js:191:7)
at maybeClose (internal/child_process.js:877:16)
at Socket.<anonymous> (internal/child_process.js:334:11)
at emitOne (events.js:96:13)
at Socket.emit (events.js:188:7)
at Pipe._handle.close [as _onclose] (net.js:498:12)
I'm fairly new to node.js, but from what I understand, If i wait for the child process to complete before calling res.end(), the entire script (including the ping listener) will not work until the child process completes.
How should I go about doing this?
Problem is that your exec is asynchronous, code below it won't wait to for completion of exec and get executed... You have to end response inside callback function:
app.post("/nodedl", function(req, res) {
res.write("===Gradyncore listnener===\n")
res.write("Recived POST request from "+req.ip+" to /nodedl\n")
res.write("POST(url): "+req.body.url+"\n")
res.write("checking key...\n")
if (req.body.key==="<Insert key here>"){
res.write("Key is valid! Skipping pre-download script...\n")
} else {
res.write("Key is invalid. Running pre-download script...\n")
exec("/home/gradyn/website/projects/nodeDL/scripts/check.sh", function(error, results) {
if (results != null) {
res.write(results+"\n");
res.end();
} else if (error != null) {
res.write("Error: " + error+"\n");
res.end();
}
});
}
});

throw new RangeError node js

I'm trying to work with IBM Watson Conversation service with Node.js.
I use 'express' to post a message:
app.post( '/api/message', function(req, res) {
}
and to print the message got from the service:
conversation.message( payload, function(err, data) {
if ( err ) {
return res.status( err.code || 500 ).json( err );
}
return res.json( updateMessage( payload, data ) );
} );
I just ran the application on port 3000. While the page is not loaded and I got this error:
_http_server.js:192
throw new RangeError(`Invalid status code: ${statusCode}`);
^
RangeError: Invalid status code: 0
at ServerResponse.writeHead (_http_server.js:192:11)
at ServerResponse._implicitHeader (_http_server.js:157:8)
at ServerResponse.OutgoingMessage.end (_http_outgoing.js:573:10)
at ServerResponse.send (C:\IBM\1.Mission\2016\conversation-simple-master(1)\
conversation-simple-master\node_modules\express\lib\response.js:204:10)
at ServerResponse.json (C:\IBM\1.Mission\2016\conversation-simple-master(1)\
conversation-simple-master\node_modules\express\lib\response.js:249:15)
at C:\IBM\1.Mission\2016\conversation-simple-master(1)\conversation-simple-m
aster\app.js:86:44
at Request._callback (C:\IBM\1.Mission\2016\conversation-simple-master(1)\co
nversation-simple-master\node_modules\watson-developer-cloud\lib\requestwrapper.
js:47:7)
at self.callback (C:\IBM\1.Mission\2016\conversation-simple-master(1)\conver
sation-simple-master\node_modules\watson-developer-cloud\node_modules\request\re
quest.js:200:22)
at emitOne (events.js:77:13)
at Request.emit (events.js:169:7)
I don't think the problem is from npm, back my package... While it seems a generic problem...Thanks for you help.
Request to IBM Watson Conversation service probably ended with error with code "0" and it isn't a valid HTTP status code. This should work:
conversation.message(payload, function(err, data) {
if (err) {
return res.status(500).json(err);
}
return res.json(updateMessage(payload, data));
});

Gzip not working

I am trying to handle gzip.
My sources: zlib,compression,https(article by Rob W)
Server-Side:
app.get('*', function (req, res, next) {
if (req.headers['x-forwarded-proto'] != 'https') {
res.setHeader('Content-Type', 'text/event-stream')
res.setHeader('Cache-Control', 'no-cache')
// send a ping approx every 2 seconds
var timer = setInterval(function () {
res.write('data: ping\n\n')
// !!! this is the important part
res.flush()
}, 2000)
res.on('close', function () {
clearInterval(timer)
})
res.redirect('https://...herokuapp.com' + req.url)//req.connection.remoteAddress
}
else {
next();
}
})
Error:
events.js:85
throw er; // Unhandled 'error' event
^
Error: write after end
at ServerResponse.OutgoingMessage.write (_http_outgoing.js:413:15)
at ServerResponse.res.write (...\index.js:80:17)
at null. (...\app.js:63:17)
at wrapper [as _onTimeout] (timers.js:265:14)
at Timer.listOnTimeout (timers.js:110:15)
Process finished with exit code 1
Client side request:
<link rel="stylesheet" type="text/css" href="../.../.../....min.css.gz">
You can't res.write() after res.redirect(). The latter ends the response.
You might consider creating a dedicated route for your Server-Sent Events stream instead.

Resources