javascript 您如何将控制台消息和错误发送到警报?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20253652/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do you send console messages and errors to alert?
提问by Jenita
I would like to pass errors to an alert to warn the user they made mistake in their code even if they don't have console open.
我想将错误传递给警报,以警告用户他们在代码中犯了错误,即使他们没有打开控制台。
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);}
The appendChild throws an error when the scripts contain an error. It goes straight to the console though, and I want it to display in an alert, because it is for kids and they might not check the console. The try catch block does not catch the error. I tried it with eval(scripts).
当脚本包含错误时, appendChild 会抛出错误。它直接进入控制台,我希望它显示在警报中,因为它是为孩子们准备的,他们可能不会检查控制台。try catch 块不会捕获错误。我用 eval(scripts) 试过了。
try{
eval(scripts);} catch(e){ alert("error:"+e.message +" linenumber:"+e.lineNumber);}
this does work but it means that the code is executed twice, and that is very inconvenient in some cases.
这确实有效,但这意味着代码会执行两次,这在某些情况下非常不方便。
I tried monkey patching the console.error:
我试过猴子修补console.error:
console.log=function(){alert("taking over the log");}
console.error=function(){alert("taking over the log");}
but that only works when I literally use console.error. Not when an actual error is thrown. What function sends the error to the console in the case of a real error,if it isn't console.error? and can I access it and change it? Any ideas? Help would be really appreciated. Thanks Jenita
但这仅在我真正使用 console.error 时才有效。不是在抛出实际错误时。如果不是console.error,什么函数在真正错误的情况下将错误发送到控制台?我可以访问它并更改它吗?有任何想法吗?帮助将不胜感激。谢谢珍妮塔
回答by joeytwiddle
Whilst try ... catch
will work on the code that the script runs initially, as Jenita says it won't catch Syntax Errors, and also it won't catch errors thrown by callback functionswhich execute later (long after the try-catch has finished). That means no errors from any functions passed to setTimeout
or addEventListener
.
虽然try ... catch
将处理脚本最初运行的代码,正如 Jenita 所说,它不会捕获语法错误,也不会捕获稍后执行的回调函数抛出的错误(在 try-catch 完成后很久)。这意味着传递给setTimeout
或 的任何函数都没有错误addEventListener
。
However, you can try a different approach. Register an error listener on the window.
但是,您可以尝试不同的方法。在窗口上注册一个错误监听器。
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));
}
}
This will be called when an exception is thrown from a callback function. But it will also trigger on general DOM errors such as images failing to load, which you may not be interested in.
这将在回调函数抛出异常时调用。但它也会触发一般 DOM 错误,例如图像加载失败,您可能不感兴趣。
It should also fire on Syntax Errors but only if it was able to run firstso you should put it in a separate script from the one that may contain typos! (A Syntax Error later in a script will prevent valid lines at the top of the same script from running.)
它也应该在语法错误时触发,但前提是它能够首先运行,所以你应该把它放在一个单独的脚本中,与可能包含拼写错误的脚本不同!(脚本中稍后的语法错误将阻止运行同一脚本顶部的有效行。)
Unfortunately, I never found a way to get a line number from the evt
in Firefox. (Edit: Poke around, I think it might be there now.)
不幸的是,我从来没有找到从evt
Firefox 中获取行号的方法。 (编辑:戳一下,我想它现在可能在那里。)
I discovered this when trying to write FastJSLogger, an in-page logger I used back when the browser devtools were somewhat slow.
我在尝试编写FastJSLogger时发现了这一点,这是我在浏览器 devtools 有点慢时使用的页内记录器。
Desperate to catch line numbers, I started to experimentwith wrappers for setTimeout
and addEventListener
that would re-introduce try-catch around those calls. For example:
不顾一切地捕捉行号,我开始尝试使用包装器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);
};
Obviously this should be done before any event listeners are registered, and possibly even before libraries like jQuery are loaded, to prevent them from grabbing a reference to the real addEventListener
before we have been able to replace it.
显然,这应该在注册任何事件侦听器之前完成,甚至可能在加载 jQuery 之类的库之前完成,以防止它们addEventListener
在我们能够替换它之前获取对真实的引用。
回答by liviu blidar
Ok so the less elegant but highly efficient way of doing this is 'refactoring' your innate console functions. Basically any error or warnings you get are being outputted there by a javascript function that is pretty similar to the familiar console.log() function. The functions that I am talking about are console.warn(), console.info() and console.error(). now let's 're-map' what each of those do:
好吧,不那么优雅但高效的方法是“重构”您的先天控制台功能。基本上,您得到的任何错误或警告都由一个 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;
Now, generally I would highly advise against using something like this into production and limit it to debugging purposes, but since you are trying to develop a functionality that shows the output of the console, the lines are blurry there, so I'll leave it up to you.
现在,通常我强烈建议不要在生产中使用这样的东西并将其限制为调试目的,但是由于您正在尝试开发显示控制台输出的功能,因此那里的线条很模糊,所以我会留下它由你决定。
回答by Wyatt
You could wrap the script in its own try/catch, something like:
您可以将脚本包装在自己的 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);