6

I'm new to Node.JS and am stuck with an EMFILE error. I'm after a way of catching the EMFILE exception, and handling it in code.

There seems to be many questions about the "Error: EMFILE, Too many open files" error, but most answers seem to be along the lines of "Increase your ulimit".

My first question is, how do I catch this exception? When I run the below code with many connections, it raises the EMFILE error:

  stream = net.createConnection(port, host);

  stream.addListener('connect', function() {
    return stream.write(request);
  });
  stream.addListener('data', function(data) {
    return console.log(data);
  });
  stream.addListener('end', function() {
    stream.end();
    return callback();
  });
  stream.addListener('timeout', function() {
    stream.destroy();
    console.log("timeout");
    return callback();
  });
  stream.addListener('error', function(e) {
    console.log("this never gets called");
    return
  });

The exception isn't being caught in the 'error' listener. I've tried to wrap the above in a try{} catch (e) {} and nothing happens. I've used a callback method for createConnection, and it doesn't return any errors.

The only way I have been able to catch the exception is with:

process.on('uncaughtException', function(err) {
  console.log(err);
});

which seems unsafe given it's catching everything.

And so my second question is: What is the "best practices" way to catch the error and retry the call?

I've looked at: https://github.com/isaacs/npm/blob/master/lib/utils/graceful-fs.js and Simple nodejs http proxy fails with "too many open files" as references, but I'm not sure how to apply the graceful method from npm to the createConnection call.

Thanks muchly!

Community
  • 1
  • 1
Moolio
  • 243
  • 3
  • 10

1 Answers1

3

Even if you could catch this exception, is there anything useful you would do about it? If you have a leak somewhere, you need to fix the leak, and if you have normal but very high load, then you'll need to handle this somehow. Either way, when you hit this condition, things are pretty bad in your node process.

Unfortunately, when you handle an uncaughtException event, the only safe thing to do is log an error message and then exit the process. The stack on which the exception was thrown is now gone, and deep internal confusion will likely soon result.

The best solution is to increase the number of file descriptors available to the process. The good news is that file descriptors are really cheap.

Matt Ranney
  • 1,638
  • 12
  • 12
  • I really just wanted to catch the exception as a means of learning the best way to handle this kind of an application exception. For the application specifically, I ended up creating an array with the next connection - when one connection ended, it pulled the next one from the array. – Moolio Jul 19 '11 at 03:50
  • 2
    to increase the number of file descriptors available to the process, run `ulimit -S -n 5000` on OSX – DTrejo Jul 11 '12 at 22:31
  • 2
    I'd say that the best way to handle this kind of exception is to debug the cause. EMFILE (basically a file descriptor leak in your case) isn't an exception that should ever emerge in properly functional code (unless your code really is opening a huge number of files). I'd suggest using `lsof` to debug where, how, and why the leak is occurring before trying boilerplate `try`/`catch` strategies. – Zac B Feb 04 '13 at 15:37