简体   繁体   English

如何发送控制台消息和错误以提醒?

[英]How do you send console messages and errors to alert?

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. 当脚本包含错误时,appendChild会抛出错误。 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. try catch块不会捕获错误。 I tried it with eval(scripts). 我用eval(脚本)试了一下。

   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. 但这只有在我真正使用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? 如果不是console.error,在真正的错误情况下,什么函数将错误发送到控制台? and can I access it and change it? 我可以访问并更改它吗? Any ideas? 有任何想法吗? Help would be really appreciated. 帮助将非常感激。 Thanks Jenita 谢谢Jenita

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 functions which execute later (long after the try-catch has finished). 虽然try ... catch将对脚本最初运行的代码起作用,因为Jenita说它不会捕获语法错误,并且它也不会捕获稍后执行的回调函数抛出的错误 (在try-catch之后很久)已完成)。 That means no errors from any functions passed to setTimeout or addEventListener . 这意味着传递给setTimeoutaddEventListener任何函数都没有错误。

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 first so 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. 不幸的是,我从未找到过在Firefox中获取evt的行号的方法。 (Edit: Poke around, I think it might be there now.) (编辑:逛逛,我想现在可能就在那里。)


I discovered this when trying to write FastJSLogger , an in-page logger I used back when the browser devtools were somewhat slow. 我在尝试编写FastJSLogger时发现了这一点, FastJSLogger是一个页面记录器,当浏览器devtools有点慢时我用它。

Desperate to catch line numbers, I started to experiment with wrappers for setTimeout and addEventListener that would re-introduce try-catch around those calls. 我不顾一切地想要获取行数,我开始尝试使用setTimeoutaddEventListener包装器来重新引入围绕这些调用的try-catch。 For example: 例如:

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的引用。

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. 基本上你得到的任何错误或警告都是通过javascript函数输出的,这与熟悉的console.log()函数非常相似。 The functions that I am talking about are console.warn(), console.info() and console.error(). 我正在谈论的函数是console.warn(),console.info()和console.error()。 now let's 're-map' what each of those do: 现在让我们“重新映射”每个人做的事情:

//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. 现在,通常我会强烈建议不要将这样的东西用于生产并将其限制为调试目的,但是因为你正在尝试开发一个显示控制台输出的功能,那里的线条很模糊,所以我会留下它由你决定。

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);

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

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