18

Hãy nói rằng ai đó đã viết một phương pháp như thế này trong một tập tin gọi app.js cố gắng để peform một yêu cầu XHR angainst một url phi hiện:

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

tôi có thể thấy một lỗi liên quan đến URL http://run.plnkr.co/thisis404 trong giao diện điều khiển và mạng panel:

error in console

để gỡ lỗi này, tôi muốn tìm một cách nhanh chóng mà gọi XHR này đã được thực hiện trong nguồn (tức là tìm tập tin app.js):

Vì vậy, tôi cho phép các công cụ dev chrome:

  • async debug trong cuộc gọi stack
  • debug bất kỳ XHR

Debugger thực sự dừng lại theo yêu cầu XHR, nhưng các cuộc gọi stack chỉ hiển thị các tham chiếu tới tệp angular.js "core": không có tham chiếu đếnapp.jsở bất kỳ đâu được tìm thấy.

google chrome call stack

Tôi cố gắng này với crom 36 và chrome 35. Chỉ giải pháp: tìm kiếm cho URL sai trong các cơ sở mã toàn bộ (mà trong một số trường hợp có thể khó thực hiện).

  • Chế độ gỡ lỗi không đồng bộ phải trỏ đến app.js ở đâu đó trong ngăn xếp?
  • Có cách nào để theo dõi dễ dàng tệp này app.js từ lỗi bảng điều khiển không?

Với yêu cầu XHR vani (tức là không góc cạnh), XHR debug gọi stack hiển thị cuộc gọi XHR trong app.js (đó là dễ dàng hơn để gỡ rối trong trường hợp này):

enter image description here

Full ví dụ ở đây: http://plnkr.co/edit/lnCRpv?p=preview

[EDIT] Như tôi đã được hỏi: Angular.js không được rút gọn trong các thử nghiệm của tôi.

Trả lời

10

Vì vậy, bạn thấy, vấn đề này chủ yếu là do $ http của góc cạnh hút. Xin lỗi vì điều đó.

Hãy thử sử dụng thư viện bluebird, vì nó cung cấp các dấu vết ngăn xếp dài.

Promise.longStackTraces(); 
Promise.resolve($http.get('...')); 

Bạn nhận được các vết đống sau: (. Plunker here)

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) 

Điểm mấu quan trọng nhất là người đầu tiên: Possibly unhandled Error: [object Object].

Đúng. Một đối tượng được ném, không phải là đối tượng Error thực, với thuộc tính stack được đính kèm. Để tham khảo, dưới đây là cách ném lỗi và giữ ngăn xếp của nó cùng với nó: https://github.com/Ralt/newerror/blob/master/index.js

Vì vậy, cách khắc phục điều này? Điều này tùy thuộc vào một số quyết định:

  • Bạn có muốn thêm lib Promise thích hợp cho phép theo dõi ngăn xếp dài không?
  • Bạn có muốn sử dụng một lib xhr khác ném lỗi chính xác không?

Nếu bạn muốn thêm lib Promise thực, hãy sử dụng bluebird. AFAIK, nó là một trong số ít cung cấp dấu vết ngăn xếp dài và đó là dấu vết nhanh nhất.

Đối với một lib thích hợp để ném lỗi thực sự, tôi e rằng bạn không may mắn ở đó. Viết một tùy chỉnh với sự hỗ trợ cho các trình duyệt bạn muốn là không thực sự khó khăn mặc dù. Với không hỗ trợ IE8, công trình này (với 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(); 
    }); 
} 

(Plunker here.)

Như bạn thấy, stack trace là thông tin:

correct stack trace

+2

Vâng, câu trả lời này là đúng - điều này là bởi vì Bluebird không unhandled từ chối theo dõi và góc không - xem [** Câu hỏi này **] (http://stackoverflow.com/questions/23984471/how-do-i-use-bluebird-with-angular) về cách sử dụng bluebird với AngularJS. AngularJS hứa hẹn có dấu vết ngăn xếp rất xấu mà làm việc với họ trong các tình huống thế giới thực sự thực sự khó khăn. –

+0

Chúng ta có thể sửa đổi chức năng http của góc để sử dụng bluebird, để nó có thể hoạt động mà không cần sửa đổi các dự án hiện có? Điều gì về những điều sau đây: http://plnkr.co/edit/1boCEqUjSLx8zGX2uqSo – David

1

Yêu cầu XHR được xếp chồng lên nhau trong $http.pendingRequests mảng và được gửi sau. Đó là lý do tại sao bạn không thể tìm thấy một liên kết trực tiếp giữa nơi mà $http được gọi và nơi yêu cầu XHR thực tế được thực hiện.

Nếu bạn muốn biết chức năng nào được gọi là $http, bạn phải đặt điểm ngắt trong hàm $http.

Nó đánh bại toàn bộ mục đích "XHR breakpoints" theo ý kiến ​​của tôi.

0

Một lựa chọn mà đến trong tâm trí của tôi là tạo ra một mô-đun cho $ http gỡ lỗi mà bạn có thể thêm nó như là một phụ thuộc trong mô-đun chính của bạn bất cứ khi nào bạn cần phải gỡ lỗi các cuộc gọi http $. Có một người trang trí cho dịch vụ $ http có thể được đăng ký mà chỉ cần đăng nhập các đối số của cuộc gọi chuyển tiếp nó đến dịch vụ $ http. Có một breakpoint có thể được thiết lập quá.

Tôi đã tạo một ví dụ làm việc đơn giản here. Tôi mong nó sẽ có ích.

Ví dụ $ http logger trang trí thực hiện:

var httpDebugging = angular.module('http-debugging', []); 

httpDebugging.decorator('$http', function ($delegate) { 
    var debugAware = function (fnCallback) { 
    return function() { 
     var result = fnCallback.apply(this, arguments);  
     console.log('$http decorator: ', arguments); 
     return result; 
    }; 
    }; 

    for(var prop in $delegate) { 
    if (angular.isFunction($delegate[prop])) { 
     $delegate[prop] = debugAware($delegate[prop]); 
    } 
    } 

    return $delegate; 
}); 
+0

Xin chào, điều này cung cấp thông tin với $ http đã được gọi, điều này rất hữu ích, nhưng việc đặt điểm ngắt trên hàm $ http đạt được như nhau. Có thể trích xuất người gọi (và tốt hơn là, dòng số không, bắt đầu yêu cầu $ http? – David

+0

Có, mua thêm điểm ngắt trên câu lệnh console.log(), bạn có thể thấy hàm từ nơi cuộc gọi được thực hiện lần đầu tiên javascript callstack. –

+0

Tuyệt vời. Tôi sẽ cập nhật nó để bao gồm toàn bộ callstack bằng cách sử dụng http://www.stacktracejs.com/ – David

Các vấn đề liên quan