事件处理程序javascript的全局错误日志记录

时间:2011-02-10 08:16:03

标签: javascript logging error-handling

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

可能的解决方案:

我使用一种方法来跨浏览器注册事件。我可以修改它来做这样的事情:

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

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

问题:

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

1 个答案:

答案 0 :(得分: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)将返回一个函数,该函数在调用它的任何上下文中运行原始函数,并转发任意数量的参数。