2011-02-10 130 views
0

我想记录浏览器端JavaScript代码中的所有错误。我在这里和网上看到了很多关于window.onerror的讨论,很明显它不能跨浏览器工作。所以,我打算用try-catch来包装顶层输入函数。麻烦的是,我的很多代码都是事件处理程序。我还没有测试过它,但我确信无论事件处理函数是在哪里定义的,抛出的错误都会直接触发调用它的浏览器实现,而不是事件函数声明代码。我唯一的选择是在每个错误处理程序中声明抛出,捕获和错误日志调用,即使是最小的匿名调用。我不喜欢那一点。事件处理程序的全局错误日志记录javascript

一种可能的解决方案:

我使用一种方法越过浏览器寄存器的事件。我可以修改它来做这样的事情:

function registerEventHandler(object, handlerRef) { 
    var wrapperFunction = function(evt) { 
    try {   
    handlerRef(evt); 
    } catch { 
    logError(error); 
    } 
    registerEvent(object, wrapperFunction); 
} 

这个实现有一个主要问题。我经常保留对事件处理函数的引用,以便稍后注销它们。这将不起作用,因为注册为处理函数的函数将是包装器,而不是原始包装器。对此的答案是实现一个包装 - >包装映射对象,并在取消注册时使用它。

问题:

我敢说你的JavaScript魔术师拿出比这更聪明的解决方案。也许这可以通过在注册之前以某种方式增强事件处理函数来完成?这是我的JavaScript知识。你呢?

回答

1

我经常保持对事件 处理函数的引用,以 后来注销它们。这将不会 工作,因为注册为 处理程序的函数将是包装程序,而不是原来的 。

为什么这是一个问题?一旦函数被包装在错误处理中,你就不再关心原始函数了。包装器保持对原始函数的引用,并且包装器是注册的,而包装器是需要注销的东西。

只保留一个引用到你生成的包装函数,因为它是唯一重要的。


,也使其它自己的功能将使这一模式更可重复使用的

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)将返回运行原来在任何情况下,它被称为一个功能,并转发任意数量的参数。

+0

这是一个问题没有太大的问题,它只是更多的开销。我不想要它,我可以帮助它。 – 2011-02-10 08:43:18