2013-11-27 58 views
9

我想將錯誤傳遞給警報,以警告用戶他們在代碼中犯了錯誤,即使他們沒有打開控制檯。如何發送控制檯消息和錯誤以提醒?

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

它真的不適合我。即使是像這樣最簡單的形式: – Jenita

+0

我已將它粘貼在底部 – Jenita

回答

12

雖然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,一個頁內記錄我以前回來的時候,瀏覽器devtools是有點慢的時候發現了這個。

不顧一切地抓行數,我started to experimentsetTimeoutaddEventListener包裝,將重新圍繞這些調用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一個參考,我們已經能夠取代前它。

+1

非常感謝,這正是我需要的! – Jenita

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

嗨,我試過了,但沒有奏效。有人明白爲什麼錯誤未被appendChild附近的try catch塊捕獲。是否因爲appendChild在自己的代碼之後調用另一個函數(可能是evals),並且該函數捕獲錯誤並直接將錯誤發送到控制檯。有誰知道如何將錯誤發送到控制檯。它是錯誤類的方法嗎? – Jenita

+1

實際上它可以用於typeerrors,但不適用於語法錯誤 – Jenita

+0

它也不適用於回調函數(例如setTimeout)或事件處理程序(例如addEventListener)引發的錯誤。 – joeytwiddle

1

好吧,這樣做的不太優雅但高效的方式是'重構'您的先天控制檯功能。基本上,任何錯誤或警告都會通過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; 

現在,一般我會強烈建議不要使用這樣的投入生產,並限制在調試的目的,但因爲你正在試圖建立一個功能顯示控制檯的輸出,線條模糊,所以我會留給你。