2010-05-04 92 views
14

我正在使用ELMAH來記錄我的.net錯誤。它工作的很好,但我想擴展錯誤記錄以包含客戶端錯誤,即任意的JavaScript錯誤。我可以使用window.onerror事件捕獲錯誤,然後調用.net處理程序(.ashx)在elmah中記錄錯誤,但這只是我解決問題的一小竅門。有沒有更好的方法將客戶端錯誤記錄到elmah?使用Elmah進行客戶端錯誤日誌記錄

+0

我還想能夠記錄經典的ASP錯誤 – 2010-05-05 14:35:39

+0

現在有一個有趣的JavaScript去捕捉錯誤,可以簡單地包含在任何頁面上,但它仍然感覺像一個黑客 – 2010-05-05 14:37:26

+0

嗨丹尼爾,可以你張貼你正在使用的JavaScript? – 2010-05-13 09:14:11

回答

1

漁獲處理window.onerror事件,使Ajax調用所有JavaScript錯誤,以手動ELMAH

window.onerror = function (msg, url, linenumber) { 

//make ajax call with all error details and log error directly into the elmah database 

//show freindly error msg here to user 

//hide error from browser 
return true; 
} 

記錄錯誤沒有當時發現了更好的解決方案。

3

看看hoptoadapp.com以及他們如何做javascript報告。

這是同樣的事情,但不同的後端:-)

+0

這看起來不錯!爲什麼我之前沒有聽說過這個? :-) – 2010-12-24 17:36:48

+0

我可以幫助的好東西!你能將這個問題標記爲接受嗎? ;-) – changelog 2010-12-27 18:45:24

9

下面是一個更完整的解決方案(我想我抓住它從ELMAH網站...記不清了)

ErrorLogging.js:

window.onerror = function (msg, url, line) { 
     logError(msg, arguments.callee.trace()); 
    } 
    function logError(ex, stack) { 
     if (ex == null) return; 
     if (logErrorUrl == null) { 
      alert('logErrorUrl must be defined.'); 
      return; 
     } 

     var url = ex.fileName != null ? ex.fileName : document.location; 
     if (stack == null && ex.stack != null) stack = ex.stack; 

     // format output 
     var out = ex.message != null ? ex.name + ": " + ex.message : ex; 
     out += ": at document path '" + url + "'."; 
     if (stack != null) out += "\n at " + stack.join("\n at "); 

     // send error message 
     jQuery.ajax({ 
      type: 'POST', 
      url: logErrorUrl, 
      data: { message: out } 
     }); 
    } 

    Function.prototype.trace = function() 
    { 
     var trace = []; 
     var current = this; 
     while(current) 
     { 
      trace.push(current.signature()); 
      current = current.caller; 
     } 
     return trace; 
    } 

    Function.prototype.signature = function() 
    { 
     var signature = { 
      name: this.getName(), 
      params: [], 
      toString: function() 
      { 
       var params = this.params.length > 0 ? 
        "'" + this.params.join("', '") + "'" : ""; 
       return this.name + "(" + params + ")" 
      } 
     }; 
     if (this.arguments) 
     { 
      for(var x=0; x<this.arguments.length; x++) 
       signature.params.push(this.arguments[x]); 
     } 
     return signature; 
    } 

    Function.prototype.getName = function() 
    { 
     if (this.name) 
      return this.name; 
     var definition = this.toString().split("\n")[0]; 
     var exp = /^function ([^\s(]+).+/; 
     if (exp.test(definition)) 
      return definition.split("\n")[0].replace(exp, "$1") || "anonymous"; 
     return "anonymous"; 
    } 

佈局/母版頁:

<script src="@Url.Content("~/Scripts/ErrorLogging.js")" type="text/javascript"></script> 

<script type="text/javascript"> 
    //This needs to be here to be on everypage 
    var logErrorUrl = '@Url.Action("LogJavaScriptError", "Home")'; 
</script> 

HomeController.cs:

[HttpPost] 
    public void LogJavaScriptError(string message) { 
     ErrorSignal.FromCurrentContext().Raise(new JavaScriptErrorException(message)); 
    } 

JavaScriptErrorException.cs:

[Serializable] 
public class JavaScriptErrorException: Exception{ 
    public JavaScriptErrorException(string message) : base (message){} 
} 
+1

不起作用。 'msg'是一個字符串,它不包含字段fileName,stack ...'arguments.callee.trace()'將只返回前面的調用(即onerror處理程序)。 – Gabriel 2013-03-22 14:33:35

+1

它確實有效。msg包含所有信息減去調用堆棧。它會告訴你行號和錯誤。例如: JavaScriptErrorException:Uncaught TypeError:Object [object Array]沒有方法'hide':在文檔路徑'http:// xxxx/Reports/TableBreakdown?startDate = 02%2F27%2F2013%2009%3A44%3A46&endDate = 03 %2F27%2F2013%2009%3A44 3A46%&擊穿= TopIssues'。匿名('Uncaught TypeError:Object [object Array]'沒有方法'hide'','http:// xxxx/Reports/TableBreakdown?startDate = 02%2F27%2F2013%2009%3A44%3A46&endDate = 03%2F27%2F2013 %2009%3A44%3A46&breakdown = TopIssues','130') – rbj325 2013-03-27 21:23:48

0

看看這個。

http://joel.net/logging-errors-with-elmah-in-asp.net-mvc-3--part-5--javascript

我不得不做出上述代碼的唯一修改相關的捆綁。

我更換

...與 @ Scripts.Render( 「〜/ stacktrace.js」)

而在我的包的配置我增加了行... bundles.Add (新的ScriptBundle(「〜/ stacktrace.js」).include(「〜/ Scripts/stacktrace.js」));

這使得代碼與較新的MVC 4捆綁兼容。