4

我有以下内容:

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
  }
}

现在,第一个Error被抓住了try...catch,但第二个Error似乎没有被抓住。

几个问题:

  • 第二个Error不会因为它发生在不同的堆栈上而被捕获吗?如果是这样,我是否理解try...catch行为不受词汇限制,而是取决于当前堆栈?我是否正确解释了这一点?
  • 是否有任何经过充分探索的模式来处理此类问题?
4

3 回答 3

3

在这种情况下,您还可以使用 simpleEventEmitter来处理错误。

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....
    });
});
于 2013-07-26T20:18:54.323 回答
2

第二个错误永远不会被抛出,也不会被捕获。request在将匿名函数添加为'end事件的处理程序之前,会引发错误。

即使你有,它也不会被抓住,因为它确实在不同的堆栈上。如果你想以这种方式工作,你必须引发一个错误事件,或者只是将错误作为第一个回调参数传递给任何回调函数。(这些都是常见的约定,不是强制性的。)

于 2013-07-26T19:59:50.940 回答
2

catch捕获在执行其try块的内容时引发的错误。您的'end'处理程序是在块内创建和分配的try,但它显然不会在那里执行。它在request触发其end事件时执行,到那时该try块将被遗忘。

您通常希望在事件处理程序中捕获错误,而不是让它们渗透到堆栈中。你永远/很少想扔掉它们。

作为最后的手段,您可以为'uncaughtException'on注册一个处理程序process,它将捕获其他地方未捕获的所有异常。但这很少是正确的解决方案。http://nodejs.org/api/process.html#process_event_uncaughtexception

于 2013-07-26T20:03:01.077 回答