事件处理程序javascript的全局错误日志记录
我想记录浏览器端JavaScript代码中的所有错误。我在这里和网上看到了很多关于window.onerror的讨论,很明显,它不能跨浏览器工作。因此,我计划用try-catch包装顶级入口函数。问题是,我的很多代码都是事件处理程序。我还没有对它进行测试,但我非常确定,无论在哪里定义了事件处理程序函数,抛出的错误都将直接触发到调用它的浏览器实现,而不是事件函数声明代码。我唯一的选择是在每个错误处理程序中声明抛出、捕获和错误日志调用,即使是最小的匿名调用。我一点也不喜欢那样 可能的解决方案: 我使用一种方法跨浏览器注册事件。我可以修改它以执行以下操作:事件处理程序javascript的全局错误日志记录,javascript,logging,error-handling,Javascript,Logging,Error Handling,我想记录浏览器端JavaScript代码中的所有错误。我在这里和网上看到了很多关于window.onerror的讨论,很明显,它不能跨浏览器工作。因此,我计划用try-catch包装顶级入口函数。问题是,我的很多代码都是事件处理程序。我还没有对它进行测试,但我非常确定,无论在哪里定义了事件处理程序函数,抛出的错误都将直接触发到调用它的浏览器实现,而不是事件函数声明代码。我唯一的选择是在每个错误处理程序中声明抛出、捕获和错误日志调用,即使是最小的匿名调用。我一点也不喜欢那样 可能的解决方案: 我使
function registerEventHandler(object, handlerRef) {
var wrapperFunction = function(evt) {
try {
handlerRef(evt);
} catch {
logError(error);
}
registerEvent(object, wrapperFunction);
}
这一实施存在一个主要问题。我经常保留对事件处理函数的引用,以便以后注销它们。这将不起作用,因为注册为处理程序的函数将是包装器,而不是原始包装器。解决方法是实现一个wrapper->wrapped映射对象,并在注销时使用它
问题:
我敢说你们这些JavaScript魔术师会想出比这更聪明的解决方案。也许可以在注册之前通过某种方式增加事件处理函数来实现?就我的JavaScript知识而言,这是一个很大的挑战。你的呢
我经常提到这件事
处理函数,以便
稍后取消注册。这不会
作为注册为的函数工作
处理程序将是包装器,而不是
原版的
为什么这是一个问题?一旦函数被包装在错误处理中,您就不再真正关心原始函数了。包装器保留对原始函数的引用,包装器是已注册的,包装器是需要取消注册的
只需保留对生成的包装器函数的引用,因为它是唯一重要的
同时使其具有自己的功能将使该模式更易于重用
var protectErrors = function(fn) {
var that = this;
return function() {
try {
fn.apply(that, arguments);
} catch(error) {
logError(error);
}
};
};
var registerEventHandler = function(object, handlerRef) {
var wrapperFunction = protectErrors(handlerRef);
registerEvent(object, wrapperFunction);
};
protectErrors(fn)
将返回一个函数,该函数在调用原始函数的任何上下文中运行,并转发任意数量的参数。这不是什么问题,只是开销更大而已。我不想要它,我可以帮助它。(小更新,使protectErrors
更通用,顺便说一句)。至于开销,如果不能使用全局错误处理,唯一的选择是本地try-catch。这不是一个真正的解决方法。为什么在调用apply之前将此赋值给它?因为内部函数失去了与this
的连接。将这个
局部变量分配到内部函数之外,可以使其保持不变。