我想将错误传递给警告,警告用户他们在代码中犯了错误,即使他们没有打开控制台。
var doc=(frame.contentWindow.document || obj.contentDocument|| obj.contentWindow);
var head = doc.getElementsByTagName('head')[0];
var scriptElement = doc.createElement('script');
scriptElement.setAttribute('type', 'text/javascript');
scriptElement.text = scripts;
try{
head.appendChild(scriptElement);
}
catch(e){ alert("error:"+e.message +" linenumber:"+e.lineNumber);}
当脚本包含错误时,appendChild会抛出错误。它直接进入控制台,我希望它显示在警报中,因为它适用于孩子,他们可能不会检查控制台。 try catch块不会捕获错误。 我用eval(脚本)试了一下。
try{
eval(scripts);} catch(e){ alert("error:"+e.message +" linenumber:"+e.lineNumber);}
这确实有效,但这意味着代码执行了两次,在某些情况下非常不方便。
我试过猴子修补console.error:
console.log=function(){alert("taking over the log");}
console.error=function(){alert("taking over the log");}
但这只有在我真正使用console.error时才有效。不是在抛出实际错误时。 如果不是console.error,在真正的错误情况下,什么函数将错误发送到控制台?我可以访问并更改它吗? 有任何想法吗?帮助将非常感激。 谢谢Jenita
答案 0 :(得分:18)
虽然try ... catch
可以处理脚本最初运行的代码,但Jenita说它不会捕获语法错误,而且也不会捕获回调函数抛出的错误稍后执行(在try-catch完成后很久)。这意味着传递给setTimeout
或addEventListener
的任何函数都没有错误。
但是,您可以尝试不同的方法。在窗口上注册一个错误监听器。
window.addEventListener("error", handleError, true);
function handleError(evt) {
if (evt.message) { // Chrome sometimes provides this
alert("error: "+evt.message +" at linenumber: "+evt.lineno+" of file: "+evt.filename);
} else {
alert("error: "+evt.type+" from element: "+(evt.srcElement || evt.target));
}
}
当从回调函数抛出异常时,将调用此方法。但是它也会触发一般的DOM错误,例如图像无法加载,你可能不感兴趣。
它也应该触发语法错误,但只有当它能够先运行时,你应该把它放在一个可能包含错别字的单独脚本中! (稍后脚本中的语法错误将阻止同一脚本顶部的有效行运行。)
不幸的是,我从未找到过从Firefox中evt
获取行号的方法。 (编辑:逛逛,我想现在可能就在那里。)
我在尝试编写FastJSLogger时发现了这一点,这是我在浏览器开发工具稍慢时使用的页内记录器。
不顾一切地抓住行号,started to experiment包含setTimeout
和addEventListener
的包装器,它们会重新引入围绕这些调用的try-catch。例如:
var realAddEventListener = HTMLElement.prototype.addEventListener;
HTMLElement.prototype.addEventListener = function(type,handler,capture,other){
var newHandler = function(evt) {
try {
return handler.apply(this,arguments);
} catch (e) {
alert("error handling "+type+" event:"+e.message +" linenumber:"+e.lineNumber);
}
};
realAddEventListener.call(this,type,newHandler,capture,other);
};
显然,这应该在注册任何事件侦听器之前完成,甚至可能在加载jQuery之类的库之前完成,以防止它们在我们能够替换它之前获取对真实addEventListener
的引用。 / p>
答案 1 :(得分:3)
好吧,不那么优雅但高效的方法就是“重构”你天生的控制台功能。基本上你得到的任何错误或警告都是通过javascript函数输出的,这与熟悉的console.log()函数非常相似。我正在谈论的函数是console.warn(),console.info()和console.error()。现在让我们“重新映射”每个人做的事情:
//remap console to some other output
var console = (function(oldCons){
return {
log: function(text){
oldCons.log(text);
//custom code here to be using the 'text' variable
//for example: var content = text;
//document.getElementById(id).innerHTML = content
},
info: function (text) {
oldCons.info(text);
//custom code here to be using the 'text' variable
},
warn: function (text) {
oldCons.warn(text);
//custom code here to be using the 'text' variable
},
error: function (text) {
oldCons.error(text);
//custom code here to be using the 'text' variable
}
};
}(window.console));
//Then redefine the old console
window.console = console;
现在,我一般会高度建议不要将这样的东西用于生产并将其限制在调试目的,但是因为你正在尝试开发一个显示控制台输出的功能,那里的线路很模糊,所以我请留给你。
答案 2 :(得分:1)
您可以将脚本包装在自己的try / catch中,例如:
var doc=(frame.contentWindow.document || obj.contentDocument|| obj.contentWindow);
var head = doc.getElementsByTagName('head')[0];
var scriptElement = doc.createElement('script');
scriptElement.setAttribute('type', 'text/javascript');
scriptElement.text = "try{"+scripts+"}catch(e){console.error(e);alert('Found this error: ' + e +'. Check the console.')}"
head.appendChild(scriptElement);