如何汇总JavaScript错误?

如何汇总JavaScript错误?,javascript,error-handling,Javascript,Error Handling,在下面的代码中,我故意抛出一个错误,但在Chrome(仅用于测试目的)中,它不会被捕获。如何将错误汇总到父级的范围中 try { setTimeout(function() { console.log("Throwing Error..."); throw({message:"Ouch!"}); }, 500); } catch(e) { console.log(e.message); } Chrome回复如下: Uncaught #<Object>

在下面的代码中,我故意抛出一个错误,但在Chrome(仅用于测试目的)中,它不会被捕获。如何将错误汇总到父级的范围中

try {
  setTimeout(function() {
    console.log("Throwing Error...");
    throw({message:"Ouch!"});
  }, 500);
} catch(e) {
  console.log(e.message);
}
Chrome回复如下:

Uncaught #<Object>
  (anonymous function)

当浏览器调用
setTimeout
回调时,
抛出发生在
catch
块之后的某个时间

  setTimeout(function() {
    try {
        console.log("Throwing Error...");
        throw({message:"Ouch!"});
    } catch(e) {
        console.log(e.message);
    }
  }, 500);

catch
使用逻辑范围,而不是词汇范围)

有关如何解决requireJS的实际问题,请参见下面的编辑

问题在于
setTimeout()
函数在父级的作用域中运行,并且完成时没有错误。它计划(与系统一起)将来的回调事件,但当回调在将来发生时,父级的执行范围已完成,回调将从系统的顶层启动,就像一个新的系统事件(例如,单击事件处理程序)

虽然父闭包仍然存在,因为
setTimeout()
中的匿名函数仍然可以引用这些变量,但父范围的实际执行已经完成,因此try/catch的范围也就完成了

setTimeout()
匿名函数的执行上下文是顶级的(由系统启动),因此没有可以放入try/catch的父上下文。您可以在匿名函数中放置一个try/catch,但是从那里进行的抛出将返回到系统,这就是所谓的
setTimeout()
回调

  setTimeout(function() {
    try {
        console.log("Throwing Error...");
        throw({message:"Ouch!"});
    } catch(e) {
        console.log(e.message);
    }
  }, 500);
要让您自己的代码捕获在
setTimeout()
回调中发生的任何异常,您需要在回调中放置一个try/catch

  setTimeout(function() {
    try {
        console.log("Throwing Error...");
        throw({message:"Ouch!"});
    } catch(e) {
        console.log(e.message);
    }
  }, 500);
如果您解释了您试图解决的真正问题是什么(而不是这个制造的测试用例),我们可能会提供一些有用的选项


编辑现在您已经展示了您真正想要解决的问题。require.js库通过调用
onError
方法来启动每个错误。
onError
方法的默认实现是引发异常的方法。您可以分配自己的
onError
处理程序,并在回调中处理错误,而不是异常。这听起来是正确的选择

从requirejs来源:

/**
 * Any errors that require explicitly generates will be passed to this
 * function. Intercept/override it if you want custom error handling.
 * @param {Error} err the error object.
 */
req.onError = function (err) {
    throw err;
};

先前的回答者正确地解释了它

另一种思考方式是,它不工作,因为setTimeout完成得很好,并且在最初运行时不会抛出和异常。当您不再在try-catch块中时,它随后执行

如果您将try catch放在setTimeout函数中,它将起作用,如下所示:

  setTimeout(function() {
     try {
         console.log("Throwing Error...");
         throw({message:"Ouch!"});
     } catch(e) {
       console.log(e.message);
     }
      }, 500);

如果您还有问题,请告诉我。

像这样使用包装器函数

//包装函数
var tryable=函数(闭包、catchCallback){
闭包(函数(回调){
返回函数(){
试一试{
回调();
}捕获(e){
(e)秘书长;
}
};
});
};
函数throwException(){
抛出新错误(“Hi”);
}
tryable(功能(可捕捉){
设置超时(可捕获(ThroweException),1000);
},功能(e){
console.log(“错误:)”,e);
});

我建议您在标题/描述中使用try-catch和setTimeout。这样,当其他人在寻找类似的东西时,他们可能会发现你的问题并从中受益。我太希望这个场景能够奏效,以至于我完全忽略了显而易见的问题。我想要一个“如果有什么事情出错”的捕捉。例如,我使用的是requirejs,如果脚本请求超时,它会抛出一个错误,但我注意捕捉该错误,以便更好地为我的应用程序格式化错误。我已经更新了问题,以包含完整的脚本。感谢您在通用测试用例上给我打电话——我会记住这一点,我不认为Javascript有能力进行“捕获一切”的尝试/捕获。来自系统的事件或异步回调(计时器回调、ajax回调等)本质上不在try/catch块中,除非将每个事件或异步回调放在一个块中。您可以在自己的代码中建立一个约定,即每个系统回调或事件处理程序都要经过一个shell函数,该函数在调用实际回调之前进行了try/catch,但即使这样也不能保护您免受库自己进行事件处理或回调处理的影响。@scader-我在回答中添加了更多细节,包括如何覆盖requireJS错误。