Debugging in node.js - node.js

I build a server which get many requests and response to them.
In some cases, there is an error which cause the server to crush:
events.js:72
throw er; // Unhandled 'error' event
^
Error: ENOENT, open '/mnt/ace/0/file'
I have two problems:
the stack trace doesn't give me any information about the line in my application that cause this exception (I can't do manually debugging because it happens just when I get 1000 request or more).
I don't want that my server ould crush. I prefer that it will raise an exception, but will continue to work.
What the best implementation for this?

You can listen for that kind of stuff and not have it crash the app, but that's not always a great idea.
process.on('uncaughtException', function(err) {
console.log('Something bad happened');
console.log(err.stack);
});
In your case, have you tried checking ulimit settings? You may be having problems opening file handles under loads of 1000+.
Another way of thinking about this is to use domains (if you're using >= 0.8). Domains give you a finer grain of control over how you handle errors based on what contexts cause them.
var domain = require('domain').create();
domain.on('error', function(err) {
console.log(err);
});
domain.run(function() {
// Your code that might throw
});

Related

Meteor - How to handle external API connection errors?

I'm using a few external API's (some in timers, every minute or so) and sometimes I get some connection errors because of network problems or because the external systems are down for some reason. When I get this errors, the app restarts, and if the error persists the app continues restarting.
Any ideas on how can I ignore the connection error and keep the app running?
Code Example:
try {
var req = https.request(options, callback);
req.write(JSON.stringify(params));
req.end();
} catch (e) {
throw e;
}
Based on your code example. You're doing throw e inside your try catch. Essentially, you're catching an error and then throwing the error. Just do console.error(err) or however you want to handle that error, without throwing. This is what will cause your instance to stop.

Silently reporting errors to Papertrail

I'm working with a large Node.js application on Heroku, with logging maintained by Papertrail. I have a central error handling and logging function which, at the moment, just logs an error to the console, displays a generic "An error occurred!" dialog, and redirects a client to a specific page (depending on where the error occurred). But neither Papertrail nor Heroku detect this as a real error, and I don't get any sort of notifications or alerts if and when they occur.
At the moment, this is my function:
utilities.errorLogger = (err) => {
console.error(err);
};
I've tried to throw the error, which works like below:
utilities.errorLogger = (err) => {
throw new Error(err);
};
But then the error is displayed to the client, rather than being redirected away, leaving the end user confused. Similarly, putting the error in a try-catch block does not change anything from what I currently have (the error is logged but not picked up on by Papertrail or Heroku).
utilities.errorLogger = (err) => {
try {
throw new Error(err);
}
catch (err) {
console.error(err);
}
};
How can I silently throw an error for Papertrail and Heroku to pick up on and treat as an error, without needing to send the error to the client? I'd like to be able to silently handle the error and have the reporting go on in the background, rather than sending any of the error details to the client.
Ended up finding out the answer. I'm using KeystoneJS which comes with a default error handler that I hadn't seen before; I've modified it now to just redirect people while still being able to log the error.

Handle Socket.io EADDRINUSE error in Node, it's "OK" to have the error

I'm building and application that uses many sockets, in some cases, two socket.io servers try to start with the same tcp port (this is expected actually), so one of them crashes with Error: EADDRINUSE.
What I want is to "catch" the error and then do something about it. I mean, the error in some cases is expected, but I want to handle it properly. I can't find a way to do it.
Thanks!
Thanks to #migg for his answer. The link provided contained two solutions, this one worked for me:
process.on('uncaughtException', function(err) {
if(err.errno === 'EADDRINUSE')
console.log(...);
else
console.log(err);
process.exit(1);
});

Exception in Node server that uses http module

Please note that the above "possible answer" questions does not contain an answer to my question. I am using require("http"). In that question the person is taking a socket input variable that they can put a handler on. I do not have the same variable.
I have a very simple server that I have written in Node.
var http = require("http");
var sys = require("sys");
var httpProxy = require('http-proxy');
var proxy = httpProxy.createProxyServer({
target: "someServer"
});
http.createServer(function(request, response) {
try {
proxy.web(request,response);
} catch (err) {
sys.puts("I caught an error!");
}
}).listen(5000);
When I leave my app running, it crashes. My command line says:
events.js:72
throw er; // Unhandled 'error' event
^
Error: read ECONNRESET
at errnoException (net.js:900:11)
at TCP.onread (net.js:555:19)
It seems to crash not when server is serving files, but when it is waiting for a long time between requests.
While my code is a little more complex, I do have error catching on every callback.
Why is it crashing? What can I do?
In node, sprinkling try and catch everywhere is not the same as catching every error. (And in most cases, doing so is useless.) Asynchronous operations cannot throw useful exceptions because control long ago left the block of code that invoked the operation.
Instead, many objects emit an error event. The error event is a special case in that node will throw a "real" exception if there are no listeners for the event. Because this exception is thrown from code you do not and cannot control (ie wrap with try/catch), it goes uncaught and the process ends.
So if you do not add an error listener to sockets, a socket error will bring down the entire app.
However, your unhandled error is not coming from your http requests. The http module adds an error handler to every socket automatically, and re-emits the error as a clientError event on the Server. Because EventEmitters only throw when the event is named error, the fact that you don't handle clientError does not matter.
If we read http-proxy's documentation, we see that it also throws an error event, and you aren't listening for it. Thus, your app dies whenever there's an error fetching something from an upstream server.
Add an error handler.
proxy.on('error', function (err, req, res) {
res.writeHead(500, {
'Content-Type': 'text/plain'
});
res.end('Something went wrong.');
console.error(err);
});
Any time you see this error ("// Unhandled 'error' event"), it means you need to find out what is emitting an error event and add a listener to handle the error.

Debugging stray uncaught exceptions (ECONNRESET) in a node cluster

In my node.js app which uses the cluster module, I'm intermittently seeing errors like this:
events.js:71
throw er; // Unhandled 'error' event
^
Error: read ECONNRESET
at errnoException (net.js:863:11)
at TCP.onread (net.js:524:19)
This brings down my whole app, and so far the only way I've been able to deal with these is by binding a process.on('uncaughtException'). I'd like to figure out the underlying cause, but the above stack trace is pretty useless.
Is there some way to figure out what's causing these exceptions?
I should note that I'm seeing these only in the cluster master, not the workers, which leads me to suspect that they have something to do with the way the cluster modules does its magic in distributing connections to workers.
This answer was helpful: https://stackoverflow.com/a/11542134/233370
Basically, I installed longjohn and was then able to get the full async stack trace to figure out the underlying cause (rabbit.js in my case).
It seems that express enabled keep-alive by default.
In order to close connection after response you can add
res.set("Connection", "close");
Alternatively you can add a middleware in your app to close connection after each response:
app.use(function(req, res, next) {
res.set("Connection", "close");
next();
});

Resources