使用 Elmah 记录客户端错误

发布于 2024-08-31 09:39:35 字数 257 浏览 7 评论 0原文

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

I'm using ELMAH to log my .net errors. It's working great, but I want to extend the error logging to include client side errors, i.e arbitrary JavaScript errors. I can capture the errors using window.onerror event and then call a .net handler (.ashx) to log the error in elmah, but this is just my little hack to solve the problem. Is there a better way to log client side error to elmah?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

停滞 2024-09-07 09:39:35

这是一个更完整的解决方案(我想我从 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 ){}
}

Here's a more complete solution (I think I grabbed it from the ELMAH site... can't remember)

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";
    }

Layout/Master Page:

<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 ){}
}
給妳壹絲溫柔 2024-09-07 09:39:35

看看 hoptoadapp.com 以及他们如何进行 JavaScript 报告。

这是完全相同的事情,但后端不同:-)

Take a look at hoptoadapp.com and how they do javascript reporting.

It's the exact same thing, but a different backend :-)

Hello爱情风 2024-09-07 09:39:35

通过处理 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; 
}

当时没有找到更好的解决方案。

Catch all javascript errors by handling the window.onerror event and make ajax call to manually log error in 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; 
}

No better solution was found at the time.

救赎№ 2024-09-07 09:39:35

看看这个。

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

我必须对上述代码进行的唯一修改涉及捆绑。

我用

...替换为
@Scripts.Render("~/stacktrace.js")

在我的捆绑配置中我添加了这一行...
Bundles.Add(new ScriptBundle("~/stacktrace.js").Include("~/Scripts/stacktrace.js"));

这使得代码与较新的 MVC 4 捆绑兼容。

Take a look at this.

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

The only modification I had to make to the above code concerned the bundling.

I replaced

...with
@Scripts.Render("~/stacktrace.js")

And in my bundle config I added the line...
bundles.Add(new ScriptBundle("~/stacktrace.js").Include("~/Scripts/stacktrace.js"));

This makes the code compatible with the newer MVC 4 bundling.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文