I am new to node and what I would call, real server-side programming (vs PHP). I was setting up a user database with MongoDB, Mongoose and a simple mongoose user plugin that came with a schema and password stuff to use. You can add validation to Mongoose for your fields like so
schema.path('email').validate(function (email) {
if (this.skipValidation) return true
return email.trim().length
}, 'Please provide a valid email')
(this is not my code). I noticed though when I passed an invalid or blank email, .trim() failed and the entire server crashed. This is very worrisome to me because things like this don't happen in your good ol' WAMP stack. If you have a bug, 99.9% of the time it's just the browser that is affected.
Now that I am delving into lower level programming, do I have to be paranoid about every incoming variable to a simple function? Is there a tried-and-true error system I should follow?
Just check before using the variable with trim, if it is !null for example:
if(!email) {
return false;
}
And if you want to run your app forever, rather use PM2.
If you are interested in running forever, read this interesting post http://devo.ps/blog/goodbye-node-forever-hello-pm2/
You may consider using forever to keep your node.js program running. Even it crashes, it restarts automatically and the error is logged as well.
Note: Although you could actually catch all exceptions to prevent the node.js from crashing, it is not recommended.
One of our strategies is to make use of Node.js Domain to handle errors - http://nodejs.org/api/domain.html
You should set up a error logging node modules like Winston, once configured produces useful error/exceptions.
Have a look in this answer for how to catch error within your node implementation, though specific to expressjs but relevant.
Once you catch exceptions, it prevents unexpected crashes.
Related
When launched through the intern-runner command, my tests are still hanging--intern-runner never exits to give me a report and I can tell that the proxy server is still running on port 9000. The browser I specified through my config just remains open (and no, I did not set leaveRemoteOpen to true). I added some debug to lib/reporters/webdriver.js, because I saw that's what logged the "Tests complete" message. I could see that the topic.publish('/client/end') code was invoked, but nothing ever responded to this event. Doesn't lib/ClientSuite subscribe to this topic? From that module:
topic.subscribe('/client/end', function (sessionId) {
console.log("subscribed to '/client/end' for session", sessionId);
if (sessionId === remote.session.sessionId) {
clearHandles();
// get about:blank to always collect code coverage data from the page in case it is
// navigated away later by some other process; this happens during self-testing when
// the new Leadfoot library takes over
remote.setHeartbeatInterval(0).get('about:blank').then(lang.hitch(dfd, 'resolve'));
}
})
But nothing ever happens, and I don't see my console.log() output. Sorry if I am bringing up things that are red herrings, but I just wanted to do some initial investigation first.
All I want is for my test to end and my JUnit and LCOV reports generated! :( What could be going wrong?
And note: no error messages are logged to the command terminal from which I invoked intern-runner config=unittest/myInternConfig. No errors (obvious ones at least) appear in terminal where Selenium server is running.
Update 03/15/15: I added this info in my last comment, but maybe comments get lost in the shuffle on Stackoverflow. In our legacy DOH tests, we used Sinon to fake a server so as to not make real I/O requests to the backend server in unittests. I didn't see a problem with keeping this in the Intern tests, but apparently, there is. When I disabled the test modules that just do
var server = sinon.fakeServer.create();
(well, that, in addition to calling server.respondWith() and server.respond())
intern-runner completed, I got my reports, and etc. Then I searched for "intern with sinon" and stumbled upon https://github.com/theintern/intern/issues/47, where jason0x43 linked to his Sinon-with-Intern code at https://github.com/theintern/intern/blob/sinon/sinon.js. So, I found that very helpful--it seems that in my situation, Sinon's FakeXMLHttpRequest was ALSO faking requests to Intern's proxy server, and that was what was hanging the process.
So, after pretty much using jason0x43's sinon.js code to filter out the "real request," I re-enabled the problematic test modules, re-ran, and everything worked beautifully.
Again, no errors or any sort of warnings reported in terminal or browser console--it would be great if there could be some sort of head's up about this pitfall. Even if just in a Readme file.
(I also edited my original post to add this info.) In our legacy DOH tests, we used Sinon to fake a server so as to not make real I/O requests to the backend server in unittests. I didn't see a problem with keeping this in the Intern tests, but apparently, there is. When I disabled the test modules that just do
var server = sinon.fakeServer.create();
(well, that, in addition to calling server.respondWith() and server.respond())
intern-runner completed, I got my reports, and etc. Then I searched for "intern with sinon" and stumbled upon https://github.com/theintern/intern/issues/47, where jason0x43 linked to his Sinon-with-Intern code at https://github.com/theintern/intern/blob/sinon/sinon.js. So, I found that very helpful--it seems that in my situation, Sinon's FakeXMLHttpRequest was ALSO faking requests to Intern's proxy server, and that was what was hanging the process.
So, after pretty much using jason0x43's sinon.js code to filter out the "real request," I re-enabled the problematic test modules, re-ran, and everything worked beautifully.
Again, no errors or any sort of warnings reported in terminal or browser console--it would be great if there could be some sort of head's up about this pitfall. Even if just in a Readme file.
From this question, Sails js using models outside web server I learned how to run a command from the terminal to update records. However, when I do this the changes don't show up until I restart the server. I'm using the sails-disk adapter and v0.9
According to the source code, the application using sails-disk adapter loads the data from file only once, when the corresponding Waterline collection is being created. After that all the updates and destroys happen in the memory, then the data is being dumped to the file, but not being re-read.
That said, what's happening in your case is that once your server is running, it doesn't matter if you are changing the DB file (.tmp/disk.db) using your CLI instance, 'cause lifted Sails server won't know about the changes until it's restarted.
Long story short, the solution is simple: use another adapter. I would suggest you to check out sails-mongo or sails-redis (though the latter is still in development), for both Mongo and Redis have data auto expiry functionality (http://docs.mongodb.org/manual/tutorial/expire-data/, http://redis.io/commands/expire). Besides, sails-disk is not production-suitable anyways, so sooner or later you would need something else.
One way to accomplish deleting "expired records" over time is by rolling your own "cron-like job" in /config/bootstrap.js. In psuedo code it would look something like this:
module.exports.bootstrap = function (cb) {
setInterval(function() { < Insert Model Delete Code here> }, 300000);
cb();
};
The downside to this approach is if it throws it will stop the server. You might also take a look at kue.
I'm currently using node-fibers to write synchronous server-side code. I primarily do error handling through try-catch blocks, but there's always a possibility of an error occurring in external libraries or other little bits of asynchronous code. I'm thinking about using the new domains functionality to try to route those errors to the correct request, and I'm wondering if anyone has tried using fibers and domains in the same app.
Depending on how domains work behind the scenes, I can imagine that fibers might break some of the assumptions used to associate async code with the correct domain. Specifically, I'm worried domains might be doing something like the following to track contexts, which could break with fibers since fibers breaks the guarantee that a function will run to completion before any other code runs:
run_in_domain = function(to_run) {
var old_domain = global_domain;
global_domain = new_domain();
try {
to_run();
} finally {
global_domain = old_domain;
}
}
Has anyone successfully or unsuccessfully tried to get fibers and domains to play together?
I have written an article on how node domains work. How Node Domains Work
Basically they work similarly to process.on('uncaughtException').
I can see that the author of node-fibers states that you can use process.on('uncaughtException') to handle exceptions with node-fibers so there shouldn't be an issue. See Handling Uncaught Exceptions in a Fiber
I've been struggling for the past hours trying to find a decent tutorial on how to handle errors for a NodeJS + ExpressJS 3 api.
I've read a lot of questions/answers on SO and read the official ExpressJS guide and still cannot figure out the proper way to do such an important thing. Most of the answers I found were relevant in Express 1 or Express 2, but are not anymore and the ExpressJS Guide just describes something out of context, which makes it really hard to understand.
So here's my use case : I want to get informations about a city, using the GET /cities/:slug. If the slug doesn't exist or an error happened (with MongoDB or Mongoose for example), I want to return an error code.
Here's the relevant part of my current code :
if (err || !city) {
res.json({code:500, city:[]});
}
It's a basic example and it's working "well", but I'm pretty sure that's not the right way to do it in NodeJS.
Also, this does not stop my NodeJS instance, but some unexpected errors might. From what I read, this is not a problem in production because apparently restarting the NodeJS instance is cleaner, and third-parties handle it pretty well (read about Cluster, Forever or even Monit).
Would love to have more insights on this problem I've been overlooking for too long.
I'm working with an automated system written in nodeJS that creates on the fly nodes across the cloud connecting them by the means of the ZMQ binding for nodeJS. Sometimes I get the error Error: Address already in use, which is my bad because I have some bug somewhere. I would like to know if it's possible with the nodeJS binding of ZMQ to check the availability of the address before binding it.
It's not really what I was searching for, but in the end I decided to go for the "simple" solution and use a try-catch block to check if there is an error when binding to a host:port. In practice this is what I do:
try {
receiver.bindSync("tcp://"+host+":" + port);
}
catch (e) {
console.log(e);
}
Which is stupid and straight forward. I was looking for a more accurate way to do this (for example, as mentioned in the question, a function to check the availability of the address, rather than catching the error).