【问题标题】:How to handle Javascript errors when also using jQuery?使用 jQuery 时如何处理 Javascript 错误?
【发布时间】:2016-02-18 15:16:54
【问题描述】:

我的情况

嗨,我对 Javascript 比较陌生,所以我的问题可能很简单。 我为我的公司开发了多个网络应用程序。我经常遇到的一个问题是 Javascript 错误。我知道如何使用 try/catch 处理它们。

我想做什么

我想要么在服务器上写一个日志文件,要么给用户一些他们可以在没有调试知识的情况下发送给我的东西。 这意味着,必须通知用户在这两种情况下都发生了错误。

我已经做过的事情

我的一个想法是使用 try catch 并使用我在这里找到的代码:https://stackoverflow.com/a/6055620/3581748 让用户可以向我发送堆栈跟踪。

例子:

<button id="demo" onClick="errorHandling()">Produce error</button>
<script>
function errorHandling() {
    try {
        document.getElementById("somethingNotExisting").value * 2;
    } catch (_err) {
        window.prompt("Copy to clipboard: Ctrl+C, Enter", _err.stack);
    }
}
</script>

或在这里:https://jsfiddle.net/n79xv6nt/

最有效的方法。

问题

我有时会使用 jQuery 在我的“主”页面中嵌入脚本文件。 示例:

<div id="forScript"></div>
<script>
    $("#forScript").load('scripts/additionalScript.php');
</script>

如果我使用上面的代码(“我已经做了什么”下面的代码)。我没有得到告诉我错误发生在哪里的堆栈跟踪。相反,它指向一个 jQuery 文件。 Google Chrome 控制台显示了真正的堆栈跟踪。 另一个问题是,在获得行号后如何获取文件?在我的 IDE 中,这些行是不同的,因为中间有 php。

我的问题

在这种情况下是否有可能得到一个好的错误消息? (最好不用自己抛出错误) 如何访问附加脚本并查看 chrome 看到的相同行号? 以及如何通知用户/记录错误?

【问题讨论】:

  • 您缺少结束语:load('scripts/additionalScript.php)
  • 您可以使用errbit.github.io/errbit 之类的东西来收集您的错误,而不需要最终用户为您做任何事情。
  • 看起来你是在 not the only one 询问。除非有人有一个聪明的答案,否则这将是避免使用 jquery .load() 的充分理由。承诺会解决很多这样的混乱,但不是今天或明天。
  • @Jai,我想这就是他已经在做的事情了?

标签: javascript jquery error-handling


【解决方案1】:

信息

好的,首先看看这个链接:http://tobyho.com/2011/06/08/the-javascript-stacktrace-blog/。 它有很多关于不同浏览器和不同执行 javascript 方式的主题信息。每种浏览器和执行方法都提供了不同的可能性。

例如在 IE 中,大多数方法都行不通,有时您只能获得带有正确文件的行号。

另一种适用于大多数浏览器但只为您提供行号和文件的方法是:

window.onerror = function(message, fileURL, lineNumber){
  log(message + ': ' + fileURL + ': ' + lineNumber)
}

解决方案 1:DIY

您的解决方案是DIY (Do it Yourself) Stacktrace。使用 DIY Stacktrace,您获得的跟踪始终是正确的。不过,您需要考虑一些缺点:

  1. 它不会为您获取文件位置/行号。
  2. 它不适用于抛出的错误 - 无论是隐式的还是显式的 - 因为堆栈跟踪的构建需要明确地作为它自己的语句来完成,例如 printStackTrace。所以,你不能有一个堆栈跟踪和一个错误抛出 - 你不能吃你的蛋糕。

代码:

function printStackTrace() {
  var callstack = [];
  var isCallstackPopulated = false;
  try {
    i.dont.exist+=0; //doesn't exist- that's the point
  } catch(e) {
    if (e.stack) { //Firefox
      var lines = e.stack.split('\n');
      for (var i=0, len=lines.length; i&lt;len; i++) {
        if (lines[i].match(/^\s*[A-Za-z0-9\-_\$]+\(/)) {
          callstack.push(lines[i]);
        }
      }
      //Remove call to printStackTrace()
      callstack.shift();
      isCallstackPopulated = true;
    }
    else if (window.opera &amp;&amp; e.message) { //Opera
      var lines = e.message.split('\n');
      for (var i=0, len=lines.length; i&lt;len; i++) {
        if (lines[i].match(/^\s*[A-Za-z0-9\-_\$]+\(/)) {
          var entry = lines[i];
          //Append next line also since it has the file info
          if (lines[i+1]) {
            entry += ' at ' + lines[i+1];
            i++;
          }
          callstack.push(entry);
        }
      }
      //Remove call to printStackTrace()
      callstack.shift();
      isCallstackPopulated = true;
    }
  }
  if (!isCallstackPopulated) { //IE and Safari
    var currentFunction = arguments.callee.caller;
    while (currentFunction) {
      var fn = currentFunction.toString();
      var fname = fn.substring(fn.indexOf(&amp;quot;function&amp;quot;) + 8, fn.indexOf('')) || 'anonymous';
      callstack.push(fname);
      currentFunction = currentFunction.caller;
    }
  }
  output(callstack);
}

function output(arr) {
  //Optput however you want
  alert(arr.join('\n\n'));
}

解决方案 2:从 jsphp 文件中获取第 X 行。

使用您已经使用的方法以及此答案的“信息”部分中提供的方法,在大多数情况下,您可以获得错误发生位置的行号和文件名。
您可以使用javascript 从文件中获取实际的代码行,以便了解错误发生的位置。您可以使用 ajax(例如 jQuery $.get)来做到这一点。见以下代码:

var LineNumber = 0; //your line number from error here.
$.ajax({
    type: 'GET',
    url: 'YOURFILE',
    success: function (file_html) {
        // success
        console.log('success : ' + file_html);
        var file_content = "" + file_html //implicit convert to string
        var lines = file_content.split("\n");

        alert(lines[LineNumber]);

    }
});  

【讨论】:

    猜你喜欢
    • 2012-02-07
    • 2021-11-13
    • 2013-10-02
    • 2012-04-20
    • 1970-01-01
    • 2017-01-16
    • 1970-01-01
    • 2010-09-06
    • 2015-09-26
    相关资源
    最近更新 更多