【问题标题】:How to find line where exception occursin javascript in browser如何在浏览器中的javascript中查找发生异常的行
【发布时间】:2015-03-03 22:36:26
【问题描述】:

ASP.NET MVC4 购物车应用程序使用客户端浏览器实现错误日志记录

window.onerror = function (errorMsg, url, lineNumber, column, errorObj) {
    $.post('/Home/Error',
    {
        "errorMsg": errorMsg,
        "url": url,
        "lineNumber": lineNumber,
        "column": column,
        "errorobj": JSON.stringify(errorObj)
    });

这会记录有关令牌 o 的奇怪错误:

Error Uncaught SyntaxError: Unexpected token o

网址和列号略有不同:

Line 1 Column 2

Line 1 Column 10 Object {}

Line 1 Column 10 Object {}

Line 1 Column 9 Object {}

Line 1 Column 1 Object {}

行号始终为 1,对象为空。 有 4 种不同的列号:1,2,9,10

如何在 javascript 中找到导致此异常的行? 在无法访问的客户端浏览器中发生异常。唯一的办法是 将js代码行信息发送到浏览器。

这些页面包含很少的 ajax 调用。 /Store/Browse 包含将商品添加到购物车的 ajax:

   request = $.post('/Store/AddToCart',
        serializedData, function (response) {
            $("#cart-status").text(response.Total);
            $inputs.prop("disabled", false);
            var xx = $form[0].quantity;
            $($form[0].quantity).css("background-color", "green");
            showMessage(response.Message);
            showFadeOutMessage(response.Message);
        })
           .fail(function (jqXHR, textStatus, errorThrown) {
               alert('Error ' + textStatus);
           })
          .always(function () {
              $inputs.prop("disabled", false);
          });

可以将 lastLine 分配添加到类似的代码中

   var lastLine;
   lastLine="request = $.post('/Store/AddToCart";

   request = $.post('/Store/AddToCart',
        serializedData, function (response) {

            lastLine='$("#cart-status").text(response.Total)';
            $("#cart-status").text(response.Total);
            lastLine='$inputs.prop("disabled", false)';
            $inputs.prop("disabled", false);
            ...

并在 window.onerror 中将 lastLine 值发送到服务器,但这需要手动更改大量代码。 有没有更好的方法来找到这里发生错误的行,也许还有堆栈跟踪?

【问题讨论】:

    标签: javascript jquery asp.net ajax asp.net-mvc-4


    【解决方案1】:

    window.onerror 在 IE、Chrome 和 Firefox 之间是不同的。您的代码将在 IE 中运行。此代码适用于 IE 和 chrome。

    window.onerror = function (errorMsg, url, lineNumber, column, errorObj) {
            $.post('/Home/Error',
            {
                "errorMsg": errorMsg,
                "url": url,
                "lineNumber": lineNumber,
                "column": column,
                "errorobj": errorObj ? errorObj.stack : ''
            });
    

    在 Chrome 中 errorObj 包含三个属性:名称、堆栈和消息——但都是getter。 JSON.parse 不处理函数,getter 是一个函数。

    例如(仅限 Chrome!)

    window.onerror = function (errorMsg, url, lineNumber, column, errorObj) {
        console.log(JSON.stringify(errorObj)); // {}
        console.log(errorObj.stack); //SyntaxError: Unexpected token o
                                     //    at Object.parse (native)
                                     //    at foo (http://www.example.com/index.js:8:10)
                                     //    at ...
        console.log(errorObj.message); // Unexpected token o
        console.log(errorObj.name); // SyntaxError
    }
    

    在 IE errorObj 中它是一个简单的对象。但是errorObj.stack更清晰。

    Firefox 不发送 errorObj 参数。您需要使用 try catch 包装代码(或覆盖 JSON.parse 并使用 try catch 包装调用),然后发送 e.toString()e.stack。例如:

    var bckJSON = JSON.parse;
    JSON.parse = function () {
        try {
            bckJSON.apply(argumetns};
        } catch (e) {
            // send e.toString() + '\n' + e.stack
        }
    }
    

    抱歉之前没有用的答案...

    【讨论】:

    • 谢谢。如何使它也可以在 FireFox 中工作,在哪里添加 try/catch ?如何发送在任何浏览器中返回的所有信息?根据您的回答,chrome也返回名称,如何记录?这应该是常见的要求,在哪里可以找到通用的 onerror 处理程序,它记录来自任何浏览器的最大信息?我可以根据您的回答尝试创建它,但我希望它已经创建。
    • 1) chrome中的name参数包含在stack参数中。这种方式可以为您使用的每个浏览器提供最多的数据。您不需要添加更多特殊句柄
    • 2) 如果我是对的,这是 JSON.parse 抛出此异常。因此,覆盖 JSON.parse 并使用 try/catch 包装调用。
    • send e.toString() and e.stack - 怎么做? answer中没有e变量
    • try { //Your code } catch (e) { // e is exeption object }
    【解决方案2】:

    使用对象调用 JSON.parse 时会出现错误“错误未捕获语法错误:意外标记 o”。 可能发生此代码 -

    JSON.parse({});

    【讨论】:

    • 正如您在相关链接中看到的,没有使用 JSON.parse()。一些 SO 答案指出,如果响应内容类型声明为 json,则 jQuery 可能会在内部调用它。应用程序应返回正确的 json。如何找到发生此异常的行或解决此问题的其他方法?
    • 你使用什么版本的 Jquery?
    • 我正在使用 jquery-1.11.1.js 文件
    【解决方案3】:

    JQuery,在某些情况下,使用 $.parseJSON 来转换 ajax 查询而不检查数据是否为字符串。我不知道什么时候会发生这种情况。

    您可以通过这种方式解决:

    (使用 $.parseJSON 因为它处理没有 JSON 库的浏览器)

    JsonParseFix.js

    function isString(value) {
        return Object.prototype.toString.call(value) === "[object String]";
    }
    
    var bckJSONparse = $.parseJSON;
    $.parseJSON = function(text, reviver) {
        if (!isString(text)) {return text};
    
        bckJSONparse.apply(arguments);
    };
    

    test.js

    function test(value, message) {
        try {
           $.parseJSON(value);
           console.log('Test succeed: ' + message);
        } catch (e) {
           alert('Test failed: ' + message);
        }
    }
    
    test({}, 'Empty object');
    test('<', 'UnSupported strings'); // Failed! 
    

    Angular 以类似的方式解决此问题 (angular.fromJson documentation)。

    (对不起我的英语......)

    【讨论】:

    • 谢谢。如何使用此答案查找 javascript 中发生异常的代码行?
    • ajax请求返回时出现异常。这不是您的代码,而是 JQuery 代码。调用堆栈不会帮助您,因为这发生在异步请求返回时。您需要了解为什么会发生这种情况,而不是在哪里发生。如果你想了解原因,你需要调试 jquery 代码。
    • 如果我的应用程序在响应标头中返回内容类型 json 但在响应正文中返回无效 json,可能会发生这种情况。如何诊断呢?是否应该将 $.parseJSON 日志文本参数覆盖到其他想法的服务器?
    • 这有助于您了解问题是否出在此函数中,而不是为什么会发生这种情况。我认为你需要; 1)在服务器中将用户浏览器保存在日志中,可能在某些浏览器中出现异常。如果是这种情况,请重现问题并调试 jquery 代码。 2)如果这没有帮助。将 jquery 代码替换为在功能完成时将日志发送到服务器的临时版本(v1.11.1 中的第 9189 行)。您需要发送参数 - 标头、响应和 s.dataTypes。大多数情况下,这些参数决定了要发生的转换类型。
    • (我,在那种情况下,我会选择解决我在回复中显示的问题),但如果你选择研究这个问题,我会很高兴你分享结果
    【解决方案4】:

    基于 Elad 的 andwer 和 cmets,我创建了以下在 IE、Chrome 和 FireFox 中返回调用堆栈的方法:

    window.onerror = function (errorMsg, url, lineNumber, column, errorObj) {
        var stack;
        // Firefox does not send errorObj argument. Wrap the code with try catch 
        // and send e.toString() and e.stack.
        try {
            stack = errorObj ? errorObj.stack : '';
        } catch (e) {
            stack = e.toString() + " stack " + e.stack;
        }
    
        $.ajax('/api/errorlog?' + $.param({
            errorMsg: errorMsg,
            url: url,
            lineNumber: lineNumber,
            column: column
        }),
          {
              data: JSON.stringify({ stack: stack }),
              type: 'POST',
              dataType: 'json',
              contentType: "application/json"
          });
        alert(errorMsg + ' Line ' + lineNumber + ' Column ' + column + '\n\n' + stack);
    };
    

    【讨论】:

    • 这不是 FF 的解决方案。 FF 中的表达式 errorObj ? errorObj.stack : ''; 将返回 null 而不是异常。即使您在 window.error 中抛出异常,这也无济于事,因为堆栈跟踪仅包含 window.error 函数。您需要包装引发异常的行
    • 在 Firefox 中堆栈跟踪也由此代码返回。为什么 ?也许 FireFox 也会返回 errorObj.stack。
    猜你喜欢
    • 2020-03-24
    • 1970-01-01
    • 1970-01-01
    • 2021-07-14
    • 2019-12-24
    • 2011-08-25
    • 2020-03-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多