2010-05-04 101 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捆绑兼容。