4

I've got the following:

var  http = require('http');

server = http.createServer(function(request, response) { 
  try {
    // Register a callback: this happens on a new stack on some later tick
    request.on('end', function() {
      throw new Error; // Not caught
    })

    throw new Error; // Caught below
  }
  catch (e) {
    // Handle logic
  }
}

Now, the first Error gets caught in the try...catch, but the second Error does not appear to be getting caught.

A couple questions:

  • Does the second Error not get caught because it occurs on a different stack? If so, am I to understand that try...catch behavior is not lexically bound, but depends instead on the current stack? Am I interpreting this correctly?
  • Are there any well-explored patterns to handle this type of problem?
Dmitry Minkovsky
  • 36,185
  • 26
  • 116
  • 160
  • I believe you're right about the cause of the issue. Can't think of a solution though... :( (except for another `try/catch` inside the callback, but I don't think that's what you're looking for). – bfavaretto Jul 26 '13 at 19:57
  • possible duplicate of [Is it possible to catch exceptions thrown in a JavaScript async callback?](http://stackoverflow.com/questions/3677783/is-it-possible-to-catch-exceptions-thrown-in-a-javascript-async-callback). The answer here might also help: http://stackoverflow.com/questions/5816436/error-handling-in-asynchronous-node-js-calls?rq=1 – bfavaretto Jul 26 '13 at 19:59
  • 1
    Use [Domains](http://nodejs.org/api/domain.html). – gustavohenke Jul 26 '13 at 20:03

3 Answers3

3

You could also use a simple EventEmitter to handle an error in a case like this.

var http = require('http');
var EventEmitter = require("events").EventEmitter; 

server = http.createServer(function(request, response) { 
    var errorHandler = new EventEmitter;
    // Register a callback: this happens on a new stack on some later tick
    request.on('end', function() {
      if(someCondition) {
        errorHandler.emit("error", new Error("Something went terribly wrong"));
      }
    });

    errorHandler.on("error", function(err) {
      // tell me what the trouble is....
    });
});
Morgan ARR Allen
  • 10,556
  • 3
  • 35
  • 33
2

The second error is never thrown, nor caught. You throw an error before you add your anonymous function as a handler for request's end event.

Even if you had, it isn't going to be caught, as it is indeed on a different stack. You must raise an error event if you want to work this way, or simply pass error as the first callback parameter to any callback function. (These are both common conventions, not mandates.)

Brad
  • 159,648
  • 54
  • 349
  • 530
2

catch catches Errors that are thrown while executing the content of its try block. Your 'end' handler is created and assigned inside the try block, but it obviously doesn't execute there. It executes when request fires its end event, and the try block will be long forgotten by then.

You'll generally want to catch errors within your event handler and not let them percolate up through the stack. You'll never/rarely want to throw them.

As a last resort, you can register an handler for 'uncaughtException' on process, which will catch all exceptions that aren't caught elsewhere. But that's rarely the right solution. http://nodejs.org/api/process.html#process_event_uncaughtexception

adpalumbo
  • 3,031
  • 12
  • 12