繁体   English   中英

如何在Chrome的JavaScript中覆盖/扩展ReferenceError?

[英]How can I override/extend ReferenceError in Chrome's JavaScript?

为了使调试更容易,我正在捕获Chrome中的所有控制台日志,以便提交反馈条目的用户也将所有日志提交到我们的服务器。 当有人遇到生产中的问题时,我首先可以让他们重新开始工作,这样我就可以坐下来更彻底地查看所有日志,以确定用户在生产中遇到的任何问题的根本原因。

我用来捕获日志的技术涉及覆盖console.log,以便在第一个参数中输入的所有文本都存储在一个数组中,同时调用遗留函数,这样我仍然可以在控制台中看到日志。

问题是偶尔会出现未捕获的异常。 这些不包含在上传的日志中,因此并不总是清楚导致问题的原因。 所以我尝试通过编写一个将函数作为参数的JavaScript函数来覆盖ReferenceError,然后返回一个新函数,用它来处理它,比如将数据存储在变量中,然后调用遗留函数作为最后一步:

function overrideException(legacyFn) {  

    /** arguments for original fn **/
    return function() {

        var args = [];

        args[0] = arguments[0];

        // pass in as arguments to original function and store result to 
          // prove we overrode the ReferenceError
        output = ">> " + legacyFn.apply(this, args).stack;

        return legacyFn.apply(this, arguments);
    }           

}

为了测试overrideException函数,我在控制台上运行了以下代码:

ReferenceError = overrideException(ReferenceError);

之后,我通过手动抛出一个ReferenceError来测试返回的函数,即新的ReferenceError:

throw new ReferenceError("YES!! IT WORKS! HAHAHA!");

控制台上的结果输出是:

ReferenceError:是的!! 有用! 哈哈哈!

从overrideException函数检查全局变量output显示它确实运行:

output
  ">> ReferenceError: YES!! IT WORKS! HAHAHA!
  at ReferenceError (<anonymous>)
  at new <anonymous> (<anonymous>:18:35)
  at <anonymous>:2:7
  at Object.InjectedScript._evaluateOn (<anonymous>:562:39)
  at Object.InjectedScript._evaluateAndWrap (<anonymous>:521:52)
  at Object.InjectedScript.evaluate (<anonymous>:440:21)"

现在,事情开始分崩离析了。 在我们的代码中,我们不会知道何时发生未捕获的异常,所以我通过尝试运行不存在的函数来测试它:

ttt();

结果如下:

ReferenceError:未定义ttt

但是,与我们明确抛出错误的情况不同,在这种情况下,函数不会触发,我们只剩下遗留功能。 变量output的内容与第一次测试中的内容相同。

所以问题似乎是: 我们如何覆盖JavaScript引擎用于抛出错误的ReferenceError功能,以便它与我们抛出ReferenceError时使用的功能相同?

请注意,此时我的问题仅限于Chrome; 我正在构建Chrome Packaged应用。

出于同样的原因,我做了很多研究:我想记录错误并报告它们。

“覆盖”本机类型(无论是ReferenceErrorString还是Array )是不可能的。

Chrome会在运行任何Javascript之前绑定这些内容,因此重新定义window.ReferenceError无效。

您可以扩展ReferenceError喜欢的东西ReferenceError.prototype.extension = function() { return 0; } ReferenceError.prototype.extension = function() { return 0; } ,甚至覆盖toString (一致性,尝试在页面,而不是开发工具上)。

这对你没有多大帮助。

但不要担心....

(1)使用window.onerror获取文件名,1索引行号和未捕获错误的0索引位置,以及错误本身。

var errorData = [];
onerror = function(message, file, line, position, error) {
    errorData.push({message:message, file:file, line:line, position:position, error:error});
};

请看小提琴的例子。 由于OP是特定于Chrome的,因此仅在Chrome中进行了测试。

由于改进的(2)(1),这不再是必要的,但在这里我离开这个第二种技术的完整性,并且由于onerror不能保证在所有浏览器所有的错误工作 您有时也会看到以下内容:

var errors = [];
function protectedFunction(f) {
    return function() {
        try {
            f.apply(this, arguments);
        } catch(e) {
            errors.push(e);
            throw e;
        }
    };
}
setTimeout = protectedFunction(setTimeout);
setInterval = protectedFunction(setInterval);
etc...

仅供参考,所有这些与谷歌闭包编译器库中的goog.debug非常类似,它是在Gmail开发过程中创建的,旨在实现这一目标。 特别感兴趣的是goog.debug.ErrorHandlergoog.debug.ErrorReporter

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM