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

How do you send console messages and errors to alert?

本文关键字:错误 何发送 控制台 消息      更新时间:2023-11-08

我想将错误传递给警报,以警告用户他们在代码中犯了错误,即使他们没有打开控制台。

    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.log=function(){alert("taking over the log");}
       console.error=function(){alert("taking over the log");}

但只有当我真正使用console.error时,这才有效。当抛出实际错误时,这就不起作用了。在发生实际错误时,如果不是console.error,哪个函数会将错误发送到控制台?我可以访问并更改它吗?有什么想法吗?非常感谢您的帮助。感谢Jenita

虽然try ... catch将处理脚本最初运行的代码,正如Jenita所说,它不会捕获语法错误,而且它也不会捕获稍后执行的回调函数引发的错误(在try-catch完成很久之后)。这意味着传递给setTimeoutaddEventListener的任何函数都没有错误。

但是,您可以尝试不同的方法。在窗口上注册一个错误侦听器。

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时发现了这一点,这是一个页面内记录器,我在浏览器开发工具有点慢的时候使用过。

为了获取行号,我开始尝试使用setTimeoutaddEventListener的包装器,在这些调用周围重新引入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的引用

好的,所以做这件事的不那么优雅但高效的方法是"重构"你固有的控制台功能。基本上,您收到的任何错误或警告都会由一个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;

现在,一般来说,我强烈建议不要在生产中使用这样的东西,并将其限制在调试目的,但由于您正试图开发一种显示控制台输出的功能,因此线条很模糊,所以我将由您决定。

您可以将脚本包装在自己的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);