My express server is not exiting with both ctrl + c and process.exit(1) - node.js

I am getting an error message:
listen EADDRINUSE: address already in use :::3000.
When I tried after removing the server starting code(i.e app.listen part) nothing is happening
const path = require('path')
const express = require('express')
//var publicPathDirectory = path.join(__dirname,"../public")
const app = express()
app.listen(3000,()=>{
console.log('server started')
})
process.on('SIGINT', function() {
console.log( "\nGracefully shutting down from SIGINT (Ctrl-C)" );
// some other closing procedures go here
process.exit(1);
});

I've had this happen to me before, where even though I quit the node server with CTRL+C, it still is hogging port 3000. You can kill node with:
pkill -f node
Potentially related to Node.js Port 3000 already in use but it actually isn't?

Use number 1 inside exit only when you have an exit with failure. To force exit do not use number inside exit().
process.exit()
Please take a look at here. May be you can understand. link

Related

ExpressJS Node Process won't end "normally"

NodeJS v 16.15.1 Windows 10.
Since a few days, neither nodemon nor VSCode can end node processes which use app.listen() of express. When the code changes we see:
[nodemon] restarting due to changes...
But nothing happens after that. We have to kill the processes manually in task manager.
'use strict';
const express = require('express');
const app = express();
const PORT = 8040;
// The PROBLEMATIC line:
app.listen(PORT, () => {
console.log(`Started on http://localhost:${PORT} (PID: ${process.pid})`);
});
If I remove "The PROBLEMATIC line" then nodemon/vscode can restart the process.
There is NO error message, the app just does not exit. For example by entering rs:
Nothing happens, no matter how long I wait.
Using nodemon --signal SIGTERM makes no difference, the process never sees the SIGTERM.
Using the package why-is-node-running we see:
There are 5 handle(s) keeping the process running
# TCPSERVERWRAP
C:\services\overview\node_modules\express\lib\application.js:635 - return server.listen.apply(server, arguments);
C:\services\overview\src\tmp2.js:6 - app.listen(PORT, () => {
# TTYWRAP
C:\services\overview\src\tmp2.js:7 - console.log(`Started on http://localhost:${PORT} (PID: ${process.pid})`);
# HTTPINCOMINGMESSAGE
(unknown stack trace)
# HTTPINCOMINGMESSAGE
(unknown stack trace)
# TickObject
(unknown stack trace)
You want end the node/nodemon process? Why not using ctrl + c instead

It won't accept command line after first run

I ran my first server and seems fine except that it won't stop running. I cannot even type anything else in the command line. I will appreciate any help
Here is the code I ran
const http = require('http');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) =>
{
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('In the name of Allah, the Most Gracious, the Most Merciful.');
});
server.listen(port, hostname, () =>
{
console.log(`Server running at http://${hostname}:${port}/`);
});
But the problem is not the code, rather how to get back to this command line
$papus#QuantumOne MINGW64 /c/Projects/firstServer so that I can start retyping again on the command line without closing everything down and restart the whole process.
right now it gets stuck on Server running at http://127.0.0.1:3000 forever
Because it is a server and it is not supposed to stop after a time.
You can shut down by pressing ctrl + c
Or you can program a certain route that will kill it programatically (i did not say it should be done)
If you want to continue using the same terminal you can run the server in background (on unix systems it is done by adding & at the end of the start command)
You can also look at process manager for nodejs server like pm2

mocha watching fails under npm

I have a very simple Koa application:
var app = module.exports = require("koa")();
app.use(function *(){
this.body = "Koa says Hi!";
});
var port = process.env.PORT || (process.argv[2] || 3000);
port = (typeof port === "number") ? port : 3000;
app.listen(port);
console.log("Application started. Listening on port:" + port);
that I test with mocha and supertest like this;
var app = require("../");
var request = require("supertest").agent(app.listen());
describe("Our amazing site", function () {
it("has a nice welcoming message", function (done) {
request
.get("/")
.expect("Koa says Hi!")
.end(done);
});
});
I want to watch my files for changes and use the -w flag like this
mocha -u bdd -R min -w
That works fine. I change a file, the test is reexcuted and all is well.
But, very strangely, if I move that command into my package.json file as a script, like this:
"scripts": {
"watch:test": "mocha -u bdd -R min -w"
},
The first time I run the command it works, when I make a change that is picked up but now the test fails with:
1) Uncaught error outside test suite:
Uncaught Error: listen EADDRINUSE :::3000
at Object.exports._errnoException (util.js:837:11)
at exports._exceptionWithHostPort (util.js:860:20)
at Server._listen2 (net.js:1231:14)
at listen (net.js:1267:10)
at Server.listen (net.js:1363:5)
at Application.app.listen (node_modules/koa/lib/application.js:70:24)
at Object.<anonymous> (index.js:10:5)
at Object.<anonymous> (test/site.spec.js:1:73)
at Array.forEach (native)
at StatWatcher._handle.onchange (fs.js:1285:10)
That error will not go away until I stop mocha and then restart it.
Why does it behave differently when run via npm?
What can I do to fix this?
Ok - I found the solution. This has to do with that I'm starting an app twice, when under test. And not closing both.
To start testing with Supertest you construct a request like this: var request = require("supertest").agent(app.listen());. Btw the app.listen() is the same thing as we do in our application.
Since we are watching our files for changes the server never gets close. On the next run of the test it starts again: var request = require("supertest").agent(app.listen()); and the "Address is in use".
The solution is simple: just start listening when you are not running under test. A simple way to do that is by checking for a module parent in your application:
if(!module.parent) {
app.listen();
}

How to debug Node.JS child forked process?

I'm trying to debug the child Node.JS process created using:
var child = require('child_process');
child .fork(__dirname + '/task.js');
The problem is that when running in IntelliJ/WebStorm both parent and child process start on the same port.
debugger listening on port 40893
debugger listening on port 40893
So it only debugs the parent process.
Is there any way to set IntelliJ to debug the child process or force it to start on a different port so I can connect it in Remote debug?
Yes. You have to spawn your process in a new port. There is a workaround to debug with clusters, in the same way you can do:
Start your app with the --debug command and then:
var child = require('child_process');
var debug = typeof v8debug === 'object';
if (debug) {
//Set an unused port number.
process.execArgv.push('--debug=' + (40894));
}
child.fork(__dirname + '/task.js');
debugger listening on port 40894
It is a known bug in node.js that has been recently fixed (although not backported to v0.10).
See this issue for more details: https://github.com/joyent/node/issues/5318
There is a workaround where you alter the command-line for each worker process, although the API was not meant to be used this way (the workaround might stop working in the future). Here is the source code from the github issue:
var cluster = require('cluster');
var http = require('http');
if (cluster.isMaster) {
var debug = process.execArgv.indexOf('--debug') !== -1;
cluster.setupMaster({
execArgv: process.execArgv.filter(function(s) { return s !== '--debug' })
});
for (var i = 0; i < 2; ++i) {
if (debug) cluster.settings.execArgv.push('--debug=' + (5859 + i));
cluster.fork();
if (debug) cluster.settings.execArgv.pop();
}
}
else {
var server = http.createServer(function(req, res) {
res.end('OK');
});
server.listen(8000);
}
Quick simple fix ( where using chrome://inspect/#devices )
var child = require('child_process');
child.fork(__dirname + '/task.js',[],{execArgv:['--inspect-brk']});
Then run your app without any --inspect-brk and the main process won't debug but the forked process will and no conflicts.
To stop a fork conflicting when debugging the main process ;
child.fork(__dirname + '/task.js',[],{execArgv:['--inspect=xxxx']});
where xxxx is some port not being used for debugging the main process. Though I haven't managed to easily connect to both at the same time in the debugger even though it reports as listening.
I find that setting the 'execArgv' attribute in the fork func will work:
const child = fork('start.js', [], {
cwd: startPath,
silent: true,
execArgv: ['--inspect=10245'] });
if "process.execArgv" doenst work you have to try:
if (debug) {
process.argv.push('--debug=' + (40894));
}
this worked for me..
There are one more modern way to debug child (or any) process with Chrome DevTools.
Start your app with arg
--inspect
like below:
node --debug=9200 --inspect app/main.js
You will see the message with URL for each child process:
Debugger listening on port 9200.
Warning: This is an experimental feature and could change at any time.
To start debugging, open the following URL in Chrome:
chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=127.0.0.1:9200/207f2ab6-5700-4fc5-b6d3-c49a4b34a311
Debugger listening on port 9201.
Warning: This is an experimental feature and could change at any time.
To start debugging, open the following URL in Chrome:
chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=127.0.0.1:9201/97be3351-2ea1-4541-b744-e720188bacfa
Debugger listening on port 9202.
Warning: This is an experimental feature and could change at any time.
To start debugging, open the following URL in Chrome:
chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=127.0.0.1:9202/8eb8384a-7167-40e9-911a-5a8b902bb8c9
If you want to debug the remote processes, just change the address 127.0.0.1 to your own.

Automate Jasmine-Node and express.js

I created a simple Webapp using express.js and want to test it with jasmine-node. Works fine so far but my problem is that I have to start the server manually every time before I can run my tests.
Could you help me on how to write a spec-helper that runs the server (with another port then my development one) just for the tests and then kills it afterwards?
This is what I do:
I have a server.js file inside the root of my node project that sets up the node application server (with express) and exports 2 methods:
exports.start = function( config, readyCallback ) {
if(!this.server) {
this.server = app.listen( config.port, function() {
console.log('Server running on port %d in %s mode', config.port, app.settings.env);
// callback to call when the server is ready
if(readyCallback) {
readyCallback();
}
});
}
};
exports.close = function() {
this.server.close();
};
The app.js file will be simple at this point:
var server = require('./server');
server.start( { port: 8000 } );
So the files/folder basic structure would be the following:
src
app.js
server.js
Having this separation will allow you to run the server normally:
node src/app.js
..and/or require it from a custom node script, which could be a node script (or a jake/grunt/whatever task) that executes your tests like this:
/** my-test-task.js */
// util that spawns a child process
var spawn = require('child_process').spawn;
// reference to our node application server
var server = require('./path/to/server.js');
// starts the server
server.start( { port: 8000 }, function() {
// on server ready launch the jasmine-node process with your test file
var jasmineNode = spawn('jasmine-node', [ '.path/to/test/file.js' ]);
// logs process stdout/stderr to the console
function logToConsole(data) {
console.log(String(data));
}
jasmineNode.stdout.on('data', logToConsole);
jasmineNode.stderr.on('data', logToConsole);
jasmineNode.on('exit', function(exitCode) {
// when jasmine-node is done, shuts down the application server
server.close();
}
});
I use Mocha - which is damn similar - but the same principle should apply: you could try requireing your app.js file in a 'beforeEach' hook inside the main describe. That should fire it up for you.
Assuming you use some code that invokes app.listen() in server.js, don't require the file on each run but only once and then have two functions like
startServer = -> app.listen(3000)
stopServer = -> app.close()
Then you can use these in beforeEach and afterEach
If you want then to go one step further in automating your testing while you develop, you can go to your terminal line and execute
jasmine-node . --autotest
Jasmine then will stay listening to every file inside your project and whenever you make changes to one it will tell if that piece of your code breaks any of your tests ;)

Resources