这可能是个糟糕的问题,但我注意到,当我使用 mootools 编写代码时,当我有一些代码经过回调、绑定(bind)并且通常不仅仅是直接的函数调用时,如果有错误,它不会被 Firebug 或 Chrome 的控制台发现,它就会默默地失败,我被迫使用 try 来追踪错误,这样就不会给你方便的信息,比如代码行失败。这就像为 IE6 编写代码一样,您所要做的只是一些不透明的消息,例如“无法读取未定义的‘x’”。
我意识到这个问题不够具体,无法问“我该如何避免这种情况”,但是否有其他人遇到过这个问题?如果遇到过,您是如何解决的?我也有点困惑如何通过 try/catch block 而不是 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' 信息。
最佳答案
我在处理 JavaScript 中的错误方面拥有丰富的经验。我主要使用 Chrome 来建立我的理解,但其中大部分也适用于 Firefox 和 Internet Explorer。
我可以立即反驳您关于静默 JavaScript 错误的假设。它们不存在,错误总是显示。 Firefox 或 Chrome 的 webdev 中可能存在错误,但错误就在那里。
错误不显示的最常见方式是您自己捕获它们。也许还为时过早。
我已经想出了我认为是捕获错误的最佳策略:
<强>1。始终抛出 Error
或从 Error
继承的东西。
例如:不是: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);
}
您不会看到此错误。 (不过 Firebug/console 会捕获它)
这是因为内部函数在它自己的事件中运行,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 函数中。所以包装调用 setTimeout
,setInterval
所有与 DOM 相关的事件,如 onclick
onload
ondocumentready
, AJAX 调用 onreadystatechanged
。
如何获得正确的堆栈跟踪(通过事件!)是另一个冗长的解释。
关于javascript - 静默的javascript错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13424993/