代码之家  ›  专栏  ›  技术社区  ›  Daniel Brink

使用Elmah记录客户端错误

  •  14
  • Daniel Brink  · 技术社区  · 16 年前

    ELMAH 记录我的.net错误。它工作得很好,但我想扩展错误日志以包括客户端错误,即任意JavaScript错误。我可以使用window.onerror事件捕获错误,然后调用.net处理程序(.ashx)将错误记录在elmah中,但这只是我解决问题的小技巧。有没有更好的方法将客户端错误记录到elmah?

    4 回复  |  直到 16 年前
        1
  •  10
  •   rbj325    13 年前

    这里有一个更完整的解决方案(我想我是从ELMAH网站抓到的。。。不记得了)

        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 ){}
    }
    
        2
  •  4
  •   changelog    15 年前

    看看hoptoadapp.com以及他们是如何进行javascript报告的。

        3
  •  1
  •   Daniel Brink    15 年前

    通过处理window.onerror事件捕获所有javascript错误,并进行ajax调用以手动记录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; 
    }
    

    当时没有找到更好的解决办法。

        4
  •  0
  •   txavier    12 年前

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

    这使代码与较新的mvc4绑定兼容。