0

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?

Joe
  • 7,922
  • 18
  • 54
  • 83
  • Duplicate of http://stackoverflow.com/questions/17245881/node-js-econnreset – jgillich Mar 25 '14 at 16:05
  • @jgillich No, it is similar. 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. – Joe Mar 25 '14 at 16:07

1 Answers1

4

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.

josh3736
  • 139,160
  • 33
  • 216
  • 263
  • Great answer! Thanks! I went crazy with my error catching. I even made a function that wraps all my callbacks in error handling. – Joe Mar 25 '14 at 20:05
  • 1
    *Something* has to be emitting a unhandled error event. **In development only,** you can listen to the [`uncaughtException` event from `process`](http://nodejs.org/api/process.html#process_event_uncaughtexception), and maybe use [longjohn](https://github.com/mattinsler/longjohn) to get a more helpful stack trace. Remember, do not do this in production, and do not just use the event to ignore the error; the only sane thing to do when you have an uncaught exception is print a stack trace and exit. – josh3736 Mar 25 '14 at 21:40
  • Thanks! Dumb question: Do I have to do anything other than require("longjohn") for longjohn to work? I added that to my code, and I'm not really seeing a difference. – Joe Mar 26 '14 at 03:07
  • 1
    I don't think so. Another approach is to use [node-inspector](https://github.com/node-inspector/node-inspector) to set a breakpoint in `uncaughtException` handler (or just write a `debugger;`) and then poke around when it breaks. – josh3736 Mar 26 '14 at 04:09