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

时间:2015-03-03 22:36:27

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

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

4 个答案:

答案 0 :(得分: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
    }
}

对以前没有用的答案感到抱歉......

答案 1 :(得分:0)

当您使用object调用JSON.parse时,会出现错误'Error Uncaught SyntaxError:Unexpected token o'。 可能这个代码发生了 -

JSON.parse({});

答案 2 :(得分:0)

在某些情况下,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)。

(抱歉我的英文......)

答案 3 :(得分:0)

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