获取$ http调用的完整调用堆栈跟踪

syl*_*ain 18 javascript ajax asynchronous google-chrome-devtools angularjs

假设有人在一个文件中编写了一个这样的方法,该文件app.js试图通过一个不存在的url来执行XHR请求:

app.controller('MainCtrl', function($scope,$http) {
  $scope.send = function() {
    $http.get('http://run.plnkr.co/thisIs404');
  };
});
Run Code Online (Sandbox Code Playgroud)

我可以http://run.plnkr.co/thisis404在控制台和网络面板中看到有关URL的错误:

控制台错误

要调试这个我想快速找到在源中进行此XHR调用的位置(即查找app.js文件):

所以我启用了chrome dev工具:

  • 调用堆栈中的异步调试
  • 调试任何XHR

调试器实际上在XHR请求上停止,但调用堆栈仅显示对angular.js"核心"文件的引用 :没有对app.js 任何地方的引用.

谷歌Chrome调用堆栈

我尝试使用铬36和铬35.只有解决方案:在整个代码库中搜索错误的URL(在某些情况下可能很难).

  • 是不是异步调试模式应该指向app.js堆栈中的somwhere?
  • 有没有办法app.js从控制台错误轻松追踪此文件?

使用vanilla XHR请求(即没有角度),XHR调试调用堆栈显示XHR调用app.js(在这种情况下更容易调试):

在此输入图像描述

这里有完整的例子:http://plnkr.co/edit/lnCRpv?p = preview

[编辑]我被问到:Angular.js在我的测试中没有缩小.

Flo*_*ine 11

所以,你看,这个问题主要是因为angular的$ http很糟糕.对于那个很抱歉.

让我们尝试使用bluebird库,因为它提供了很长的堆栈跟踪.

Promise.longStackTraces();
Promise.resolve($http.get('...'));
Run Code Online (Sandbox Code Playgroud)

您将获得以下堆栈跟踪:

Possibly unhandled Error: [object Object]
    at Promise$_rejectFromThenable (http://cdn.jsdelivr.net/bluebird/1.2.4/bluebird.js:4736:52)
    at wrappedErrback (https://code.angularjs.org/1.3.0-beta.5/angular.js:11334:78)
    at wrappedErrback (https://code.angularjs.org/1.3.0-beta.5/angular.js:11334:78)
    at wrappedErrback (https://code.angularjs.org/1.3.0-beta.5/angular.js:11334:78)
    at https://code.angularjs.org/1.3.0-beta.5/angular.js:11467:76
    at Scope.$eval (https://code.angularjs.org/1.3.0-beta.5/angular.js:12418:28)
    at Scope.$digest (https://code.angularjs.org/1.3.0-beta.5/angular.js:12230:31)
    at Scope.$apply (https://code.angularjs.org/1.3.0-beta.5/angular.js:12522:24)
    at done (https://code.angularjs.org/1.3.0-beta.5/angular.js:8207:45)
    at completeRequest (https://code.angularjs.org/1.3.0-beta.5/angular.js:8412:7) 
Run Code Online (Sandbox Code Playgroud)

(此处是Plunker.)

最重要的一行是第一行:Possibly unhandled Error: [object Object].

是的.抛出一个对象,而不是一个真实的Error对象,并stack附加属性.作为参考,这里是如何抛出错误并保持其堆栈:https://github.com/Ralt/newerror/blob/master/index.js

那么,如何解决这个问题呢?这取决于几个决定:

  • 你想添加一个能够实现长堆栈跟踪的正确Promise库吗?
  • 你想使用另一个抛出正确错误的xhr库吗?

如果要添加真正的Promise lib,请使用bluebird.AFAIK,它是为数不多的提供长堆栈跟踪的产品之一,也是最快的产品之一.

对于一个引起真正错误的正确的xhr库,我担心你在那里运气不好.编写一个支持您想要的浏览器的自定义版本并不是很难.没有IE8支持,这适用(与bluebird):

function xhr(url) {
    return new Promise(function(resolve, reject) {
        var xhr = new XMLHttpRequest();
        xhr.onload = function() {
            resolve(xhr.responseText);
        };
        xhr.onerror = reject;
        xhr.open('GET', url);
        xhr.send();
    });
}
Run Code Online (Sandbox Code Playgroud)

(此处是Plunker.)

如您所见,堆栈跟踪信息丰富:

正确的堆栈跟踪

  • 是的,这个答案是正确的 - 这是因为青鸟做未处理的排斥跟踪和角度不 - 见[**这个问题**](http://stackoverflow.com/questions/23984471/how-do-i-use-关于如何在AngularJS中使用蓝鸟的bluebird-with-angular.AngularJS承诺有非常糟糕的堆栈跟踪,这使得在真实场景中使用它们非常困难. (2认同)