Running the following server.js:
cluster(app)
.use(cluster.logger(path_to_logs))
.use(cluster.stats())
.use(cluster.pidfiles(path_to_pids))
.use(cluster.cli())
.use(cluster.repl(8888))
.listen(3000);
it works as expected. However, let's throw in an unhandled exception like so:
setTimeout(function () {
throw new Error('User generated fault.');
},5000);
Running the server with `$ node server.js, it starts and the exception is thrown after five seconds. Consequently the server is quit in what is seemingly the same as pressing ctrl+c.
However not quite. Because now trying to restart the server using $ node server.js I receive the following error:
Express server listening on port 3000
node.js:134
throw e; // process.nextTick error, or 'error' event on first tick
^
Error: EADDRINUSE, Address already in use
...
And running $ ps aux | grep node I can see that I still have two node processes running. Killing them allows me to start the server again. But since it was a manual kill, if I start the server again the same procedure starts over. 5 seconds pass, throw error, unable to restart.
This is a problem because with forever, it causes an infinite death cycle upon the first unhandled exception.
So my questions are:
Do you have any further ideas on why this might occur?
How can I listen for all exceptions and react by kill the process(es)
Is the above a bad approach?
Sorry for posting this on ServerFault aswell, but I realized this IS actually a code question.
About handling unhanded exceptions, you can use: http://nodejs.org/docs/v0.4.12/api/process.html#event_uncaughtException_ .
About the process not quitting when an error is thrown: I do not know enough about cluster, but I believe to "scale" it creates child processes, and manages them, and does not die when a child dies. Taking a basic look at the source code it seems to be throwing a series of events, try seeing what events it is throwing and gather more information.
Related
I'm building an E-commerce site, where there's an Authentication system.
I noticed that if the client login with a wrong user or password, the backend/server that works with nodemon will crach and hang in there crashed till i restart manually nodemon. This is example output error of the nodemon crash:
[nodemon] app crashed - waiting for file changes before starting...
node:internal/errors:464
ErrorCaptureStackTrace(err);
^
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent
to the client
Ofcourse, when server crashes, client can no more access or do login again till server restarts.
After some googling, i found this question and this repository that fix my problem but particulary and not as expected precisely, i dont want nodemon to restart forever on any error that occure ofcourse, but only with specifics errors that i set them -like Authentication errors as i mentionned above-.
So, my idea/question is: is there anyway to get nodemon restarts by itself in some cases of failures or errors (NOT ALL)?
Seems like you a referring to a production situation, and nodemon is a development node server, which is not intended for use in production, as the intro states:
nodemon is a tool that helps develop Node.js based applications by
automatically restarting the node application when file changes in the
directory are detected.
You should use node.js in production, instead of nodemon.
For managing your node server in production, you could use a process manager like PM2..
That said, an authentication server that crashes every time a user uses a wrong password seams very ineffective in handling a common use case. So I would advise to start with fixing the root cause, which is the buggy server, and then for recovery from incidental crashes use something like PM2.
PS:
The error you are getting looks like an express error you get when you send a response (in this case an error response) without exiting the function e.g. by using return. Because you are not returning, another res.send is called, which causes the 'ERR_HTTP_HEADERS_SENT' error. See this answer.
This is really bad since it can send your program into a loop of restarting, but if you really want it, replace app.js with your file's name and try this:
nodemon -x 'node app.js || copy /b app.js +,,'
Linux version:
nodemon -x 'node app.js || touch app.js'
Next time try a little googleing before you ask since it is most likely faster.
For some reason, every time I get this particular error
/home/pi/.pm2/logs/app-error.log last 15 lines:
0|scripts | { TimeoutError: Navigation timeout of 30000 ms exceeded
0|scripts | at Promise.then (/home/pi/node_modules/puppeteer/lib/cjs/puppeteer/common/LifecycleWatcher.js:106:111) name: 'TimeoutError' }
pm2 does not restart the node JS script.
It because that error doesnt crash the main thread of the application, it just prints the error from the puppeteer thread
Use try...catch statement to catch the error (you can log it or just do nothing) so that the script will not just hang there with the error. pm2 will be able to restart it.
I'm using pm2 to manage process in my nodejs express application (running in cluster mode).
We had 2 kind of error handler
FIRST: 'uncaughtException' will be handled with
process.on('uncaughtException', function(err){});
Actually, I do not declare an handler like this cause of letting pm2 detect died worker in this case so restart the died worker automatically.
SECOND: express error handler, I mean the error will be forwarded to express error handler, not uncaughtException handler, the error handler like below
app.use(function(err, req, res, next) {})
I also do not declare this error handler for same purpose as uncaughtException.
But pm2 does not restart node in this case.
Any idea about this problem?
Many thanks
When catching errors with express error handler or even "uncaughtException" event, the process is still running, so pm2 won`t restart it.
If you want pm2 to restart after each exception, I would suggest something like this:
process.on('uncaughtException', function(e) {
console.log('An error has occured. error is: %s and stack trace is: %s', e, e.stack);
console.log("Process will restart now.");
process.exit(1);
})
Same goes for the express error handler. When we execute process.exit method, the process will terminate and pm2 will restart it.
When using node-java package, nodemon doesn't restart when the files change. If I remove node-java package then nodemon will restart when there are file changes.
Even the manual restart (rs) is not working when using node-java package in server. Following is the behavior.
alon
And even it throws the following:
events.js:85
throw er; // Unhandled 'error' event
^
Error: listen EADDRINUSE
at exports._errnoException (util.js:746:11)
at Server._listen2 (net.js:1156:14)
at listen (net.js:1182:10)
at Server.listen (net.js:1267:5)
Since the port 4000 is being used only once in server and no where else, its behaving weird.
It seems that node-java somehow magically 'overrides' what's happening when receiving SIGUSR2 signal. In such a case, the SIGUSR2 signal (used by nodemon) to restart the app may fail terminating the app.
(Quick) Fix:
after the node-java has screwed your SIGUSR2 handling mechanism, add the following snippet of code:
process.once('SIGUSR2', function() {
process.kill(process.pid, 'SIGUSR2')
})
note that you must do this AFTER the node-java (or something which uses it, in my case it is node-tika) does its 'job' (in my case, immediately after requiring node-tika).
To be honest, I have only very little understanding, why this works and I'll be glad if someone can shed more light on this.
You can try running this command.
nodemon --signal SIGINT ./index.js
I'm new to Node.js and wish to run a program using streams. With other programs, I had to start a server simultaneously (mongodb, redis, etc) but I have no idea if I'm supposed to run one with this. Please let me know where I am going wrong and how I can rectify this.
This is the program:
var http = require('http'),
feed = 'http://isaacs.iriscouch.com/registry/_changes?feed=continuous';
function decide(cb) {
setTimeout(function () {
if (Date.now()%2) { return console.log('rejected'); }
cb();
}, 2000);
}
http.get(feed, function (res) {
decide(res.pipe.bind(res, process.stdout));
//using anonymous function instead of bind:
// decide(function () {
// res.pipe(process.stdout)
// });
});
This is the cmd output:
<b>C:\05-Employing Streams\05-Employing Streams\23-Playing with pipes>node npm_stre
am_piper.js
events.js:72
throw er; // Unhandled 'error' event
^
Error: Parse Error
at Socket.socketOnData (http.js:1583:20)
at TCP.onread (net.js:527:27)
</b>
Close nodejs app running in another shell.
Restart the terminal and run the program again.
Another server might be also using the same port that you have used for nodejs. Kill the process that is using nodejs port and run the app.
To find the PID of the application that is using port:8000
$ fuser 8000/tcp
8000/tcp: 16708
Here PID is 16708 Now kill the process using the kill [PID] command
$ kill 16708
I had the same problem. I closed terminal and restarted node. This worked for me.
Well, your script throws an error and you just need to catch it (and/or prevent it from happening). I had the same error, for me it was an already used port (EADDRINUSE).
I always do the following whenever I get such error:
// remove node_modules/
rm -rf node_modules/
// install node_modules/ again
npm install // or, yarn
and then start the project
npm start //or, yarn start
It works fine after re-installing node_modules. But I don't know if it's good practice.
Check your terminal it happen only when you have your application running on another terminal..
The port is already listening..
For what is worth, I got this error doing a clean install of nodejs and npm packages of my current linux-distribution
I've installed meteor using
npm install metor
And got the above referenced error. After wasting some time, I found out I should have used meteor's way to update itself:
meteor update
This command output, among others, the message that meteor was severely outdated (over 2 years) and that it was going to install itself using:
curl https://install.meteor.com/ | sh
Which was probably the command I should have run in the first place.
So the solution might be to upgrade/update whatever nodejs package(js) you're using.