如何在浏览器中查找javascript中发生异常的行

How to find line where exception occursin javascript in browser

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 值发送到服务器,但这需要手动更改大量代码。 有没有更好的方法来找到这里发生错误的行,也许还有堆栈跟踪?

调用对象JSON.parse时出现错误'Error Uncaught SyntaxError: Unexpected token o'。 可能会出现此代码 -

JSON.parse({});

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)。

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

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包含三个属性:name、stack和message-但都是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
    }
}

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

根据 Elad 的 andwer 和评论,我创建了以下方法,returns 在 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);
};