5

这可能是一个糟糕的问题,但我注意到,当我使用 mootools 编写代码时,当我有一些通过回调、绑定的代码时,如果有错误它不会被 Firebug 或 Chrome 的控制台接收到它只是默默地失败,我不得不使用 try 来追踪错误,这样就不会给你方便的信息,比如失败的代码行。这就像为 IE6 编写代码一样,您所要做的只是一些不透明的消息,例如“无法读取未定义的 'x'”。

我意识到这个问题不够具体,无法问“我该如何避免这种情况”,但其他人是否遇到过这个问题,如果是这样,你如何解决它?我也有点困惑 try/catch 块如何拾取错误,而不是 javascript 控制台。

编辑:

好的,我想出了一些重现错误的方法

说你有一个功能

function foo(){
   var x = value.blah;
}

foo()如果我像在控制台中正确地得到参考错误一样调用该函数。但是,如果我这样称呼它

(function(){
   foo.attempt();
})()

我在控制台中没有错误,但是如果我将 foo 更改为

function foo(){
   try{
   var x = value.blah;
   } catch(e){console.log(e)}
}

控制台将记录 e 但当然没有句柄'line:whatever'信息。

4

1 回答 1

8

我在处理 JavaScript 中的错误方面拥有丰富的经验。我主要使用 Chrome 来建立我的理解,但其中大部分也适用于 Firefox 和 Internet Explorer。

我可以立即揭穿你关于静默 JavaScript 错误的假设。它们不存在,错误总是出现。Firefox 或 Chrome 的 webdev 中可能存在错误,但错误仍然存​​在。

不出现错误的最常见方法是您自己发现了它们。也许为时过早。

我已经想出了我认为捕获错误的最佳策略:

1. 总是扔掉Errors 或继承自Errors 的东西。

例如:不是:throw "Precondition failed"但是throw new Error("Precondition failed")

这是因为错误在 JavaScript 中很奇怪(我没有别的词)。如果你想要一个堆栈跟踪(天堂是的,你想要一个堆栈跟踪),你需要抛出一个Error(而不是字符串)。

2.不要使用window.onerror这里不多说。没用的。您无法控制向此函数发送的内容。它可能是您的代码,也可能是访问者使用的损坏插件。此外,没有堆栈跟踪。

3. 拥有一个(全局)错误处理程序/何时捕获错误

JavaScript 是事件驱动的。这会产生一些意想不到的后果。观察以下代码:

try {
    setTimeout(function () {
        throw new Error("nope! :D");
    }, 1);
} catch (e) {
    console.log(e);
}

您不会看到此错误。(萤火虫/控制台会捕捉到它)

这是因为内部函数在它自己的事件中运行,而 try-catch 语句不再适用于它。正确的方法是:

try {
    setTimeout(function () {
        try {
            throw new Error("nope! :D");
        } catch (e) {
            console.log("Hell yea!", e);
        }
    }, 1);
} catch (e) {
    console.log(e);
}

或者只是制作一个将函数包装在 try-catch 中的函数:

function wrap(wrap_dat_func) {
    return function () {
        try {
            wrap_dat_func.apply(wrap_dat_func, arguments);
        } catch (e) {
            // send to error handler
        }
   }
}

像这样使用:

setTimeout(wrap(function () {
    // etc
}), 1);

所以基本上每当你生成一个新事件时,将回调包装在你的全局 try catch 函数中。所以包装对所有与 DOM 相关的事件(如AJAX 调用)setTimeout的调用。setIntervalonclick onload ondocumentreadyonreadystatechanged

如何获得正确的堆栈跟踪(通过事件!)是另一个冗长的解释。

于 2012-11-16T22:15:09.503 回答