JavaScript 异常处理

IT技术 javascript exception
2021-01-30 21:17:28

捕获 JavaScript 中抛出的所有异常的最佳技术是什么?

显然,最好的技术是使用 try...catch。但是对于异步回调等,这可能会变得棘手。

我知道 IE 和 Gecko 浏览器支持 window.onerror,但是 Opera 和 Safari 呢?

这里有一堆测试用例,我希望它们有一个集中的异常处理解决方案:

// ErrorHandler-Test1
var test = null;
test.arg = 5;
// ErrorHandler-Test2
throw (new Error("Hello"));
// ErrorHandler-Test3
throw "Hello again";
// ErrorHandler-Test4
throw {
    myMessage: "stuff",
    customProperty: 5,
    anArray: [1, 2, 3]
};
// ErrorHandler-Test5
try {
    var test2 = null;
    test2.arg = 5;
} catch(e) {
    ErrorHandler.handleError(e);
}
// ErrorHandler-Test6
try {
    throw (new Error("Goodbye"));
} catch(e) {
    ErrorHandler.handleError(e);
}
// ErrorHandler-Test7
try {
    throw "Goodbye again";
} catch(e) {
    ErrorHandler.handleError(e);
}
// ErrorHandler-Test8
try {
    throw {
        myMessage: "stuff",
        customProperty: 5,
        anArray: [1, 2, 3]
    };
} catch(e) {
    ErrorHandler.handleError(e);
}

如果您想到任何其他测试用例,请提及它们。其中一些案例提到了 ErrorHandler.handleError 方法。这只是使用 try...catch 时的建议指南。

6个回答

如果您使用jQuery 之类的库来分配所有事件处理程序,则可以组合使用window.onerror并包装 jQuery 事件处理程序代码和带有错误处理函数的就绪函数(请参阅:JavaScript 错误跟踪:为什么 window.onerror 不够)。

  • window.onerror: 捕获 IE 中的所有错误(以及 Firefox 中的大多数错误),但在 Safari 和 Opera 中不执行任何操作。
  • jQuery 事件处理程序:在所有浏览器中捕获 jQuery 事件错误。
  • jQuery 就绪功能:捕获所有浏览器中的初始化错误。
这仍然是真的吗?我刚刚onerror在 Safari + Chrome 上尝试了正常的处理方法,似乎工作正常。
2021-03-14 21:17:28
您给出的“这还不够”的原因的链接是相当陈旧的信息,现在情况并非如此。
2021-03-22 21:17:28
我已经阅读了没有提供任何解决方案的文章。我不使用 jQuery,但我担心你在暗示什么。你是说 jQuery 正在吃异常吗?!或者它们是否仅提供日志记录功能(仅在回答我的原始问题后才有用)?
2021-03-26 21:17:28
jQuery 对异常没有做任何特别的事情。但是,如果您使用 jQuery 添加所有事件,它会为您提供一个单独的位置来添加您的 try catch 语句和错误处理代码,如我的答案中的第二个链接中所述。
2021-04-05 21:17:28
提供的链接已移动:blogs.cozi.com/tech/2008/04/...
2021-04-05 21:17:28

WebKit(Safari、Chrome 等)现在似乎支持onerror.

原帖:据我所知,WebKit/Safari 不支持该onerror事件。这是一个该死的耻辱。

呃,不,不是。在问题中被问到:“但是 Opera 和 Safari 呢?”
2021-03-18 21:17:28
如在,我专门回答了问题帖子中提出的问题。
2021-04-02 21:17:28
我认为他的意思是“[我该怎么做] Opera 和 Safari [没有 window.onerror]?”
2021-04-02 21:17:28
Chrome 现在似乎支持它。
2021-04-06 21:17:28
@nickf,也许吧,但如果是这样的话,它的措辞非常糟糕,我的解释在最坏的情况下是可以理解的,在最好的情况下是最有可能的。人们投票否决我的答案是一个非常糟糕的理由,特别是考虑到问题没有 说明这一点,而其他读者可能会从肯定或否定的陈述中受益。
2021-04-13 21:17:28

实际上,jquery 方法并没有那么糟糕。看:

http://docs.jquery.com/Events/error#fn

和:

$(window).error(function(msg, url, line){
  $.post("js_error_log.php", { msg: msg, url: url, line: line });
});
ofc 不应该这样绑定的,不合逻辑!进行此投标时可能会发生许多错误(如果它甚至成功进行......)
2021-03-28 21:17:28
对于现在发现此问题的任何人 - jquery 实际上建议不要将事件绑定到 window.error 事件 - 请参阅上面的文档链接。摘录:不应将 jQuery 错误事件处理程序附加到 window 对象。[...] 改用 window.onerror。
2021-03-30 21:17:28

使用您自己的异常处理程序捕获所有异常并使用 instanceof。

$("inuput").live({
    click : function (event) {
        try {
            if (somethingGoesWrong) {
                throw new MyException();
            }
        } catch (Exception) {
            new MyExceptionHandler(Exception);
        }

    }
});

function MyExceptionHandler(Exception) {
    if (Exception instanceof TypeError || 
        Exception instanceof ReferenceError || 
        Exception instanceof RangeError ||  
        Exception instanceof SyntaxError ||     
        Exception instanceof URIError ) {
        throw Exception; // native error
     } else {
         // handle exception
     }
}

MyExcetpionHandler 将抛出本机错误,因为没有 try-catch 块。

访问http://www.nczonline.net/blog/2009/03/10/the-art-of-throwing-javascript-errors-part-2/

try-catch并不总是最好的解决方案。例如,在 Chrome 7.0 中,您在控制台窗口中丢失了漂亮的堆栈跟踪。重新抛出异常没有帮助。我不知道有什么解决方案可以保留堆栈跟踪让您对异常做出react。