如何在Chrome的JavaScript中覆盖/扩展ReferenceError
How can I override/extend ReferenceError in Chrome's JavaScript?
为了简化调试,我在 Chrome 中捕获了所有控制台日志,以便提交反馈条目的用户也将所有日志提交到我们的服务器。 当有人在生产中遇到问题时,我首先可以让他们恢复工作,这样我就可以坐下来更彻底地浏览所有日志,以确定用户在生产中遇到的任何问题的根本原因。
我用于捕获日志的技术涉及覆盖控制台.log以便在第一个参数中输入的所有文本都存储在数组中,同时调用 legacy 函数,以便我仍然可以在控制台中看到日志。
问题是当偶尔出现未捕获的异常时。这些不包含在上传的日志中,因此并不总是清楚导致问题的原因。因此,我尝试通过编写一个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!");
控制台上的结果输出为:
参考错误:是的!!它有效!哈哈哈!
从 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();
这导致:
引用错误: 未定义 ttt
但是,与我们显式抛出错误的情况不同,在这种情况下,函数不会触发,我们只剩下旧功能。变量output
的内容与第一次测试中的内容相同。
所以问题似乎是这样的:我们如何覆盖 JavaScript 引擎用来抛出错误的 ReferenceError 功能,使其与我们抛出 ReferenceError 时使用的功能相同?
请记住,我的问题目前仅限于 Chrome;我正在构建一个 Chrome 打包应用。
同样的原因,我做了相当多的研究:我想记录错误并报告它们。
"覆盖"本机类型(无论是ReferenceError
、String
还是Array
(是不可能的。
Chrome 会在运行任何 Javascript 之前绑定这些内容,因此重新定义window.ReferenceError
不起作用。
您可以使用类似 ReferenceError.prototype.extension = function() { return 0; }
的东西扩展ReferenceError
,甚至可以覆盖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...
仅供参考,所有这些都与 Google 闭包编译器库中所做的非常相似,在 goog.debug
中,在 Gmail 开发期间创建,目的是做到这一点。特别令人感兴趣的是goog.debug.ErrorHandler
和goog.debug.ErrorReporter
。
- 可扩展的画布作为Google Maps Javascript API中的覆盖
- MDN文档中关于弄清楚XUL元素的段落是什么意思:“如何将覆盖扩展转换为无重启”
- MonkeyPatching:PrimeFaces小部件扩展/覆盖
- 从引导的扩展中绘制UI覆盖
- 如何在chrome扩展中的新选项卡上加载url覆盖的脚本
- javascript原生原型:扩展、添加和覆盖方法
- Chrome.storage.sync 在重新加载扩展程序时会被覆盖
- 主干:调用扩展视图的覆盖 render() 函数
- 如何在 Sails 中扩展蓝图的功能.js而不覆盖整个蓝图
- 扩展类时继承而不是覆盖属性/方法
- 打字稿覆盖构造函数中的扩展属性
- 在 JavaScript 中扩展或覆盖函数
- 扩展菜单插入带有覆盖的新项目
- Javascript,Chrome 扩展:覆盖 cookie getter 和 setter
- 在 JavaScript 中扩展/覆盖
- 火狐扩展 - 面板元素点击被覆盖
- 如何在完全独立的.js文件中覆盖/扩展原型.js类
- 如何在Chrome的JavaScript中覆盖/扩展ReferenceError
- 在 React.js 中覆盖/扩展 ES7 类的静态属性
- Jquery javascript覆盖/扩展事件