19

Tôi có một mã với AngularJS:từ chối Có thể không được quản lý ở góc 1,6

service.doSomething() 
    .then(function(result) { 
     //do something with the result 
    }); 

Trong AngularJS 1.5.9 khi tôi có lỗi trong .then() phần như:

service.doSomething() 
    .then(function(result) { 
     var x = null; 
     var y = x.y; 
     //do something with the result 
    }); 

Tôi nhận được rõ ràng thông báo lỗi:

TypeError: Cannot read property 'y' of null

Nhưng trong phiên bản 1.6 có cùng mã tôi gặp lỗi khác nhau:

Possibly unhandled rejection: {} undefined

Tôi biết rằng điều này có liên quan đến this change, và là giải pháp duy nhất là khá đơn giản bằng cách thêm .catch() khối:

service.doSomething() 
    .then(function(result) { 
     var x = null; 
     var y = x.y; 
     //do something with the result 
    }) 
    .catch(console.error); 

Bây giờ tôi lại có những gì tôi muốn:

TypeError: Cannot read property 'y' of null

Nhưng làm thế nào để có được kết quả tương tự (lỗi chi tiết hơn) cho toàn bộ ứng dụng mà không cần thêm .catch() chặn ở mọi nơi?

Tôi đã thử nghiệm giải pháp đề nghị để vô hiệu hóa điều này bằng cách bổ sung thêm:

$qProvider.errorOnUnhandledRejections(false); 

Nhưng với điều này tình hình thậm chí còn tồi tệ hơn - Tôi không có bất cứ điều gì trong giao diện điều khiển! Lỗi được nuốt ở đâu đó và không đăng nhập. Tôi không chắc chắn nó là một vấn đề với AngularJS 1.6 hoặc với cấu hình của tôi.

Bạn có ý tưởng nào về cách "khôi phục" hành vi ghi nhật ký từ phiên bản 1.5.9 không?

EDIT:

Thêm xử lý lỗi tùy chỉnh:

.factory('$exceptionHandler', function($log) { 
    return function(exception, cause) { 
    $log.warn(exception, cause); 
    }; 
}) 

không giúp gì cả. Trong trình xử lý lỗi, tôi đã nhận được lỗi "gói".

+1

Không có ý tưởng về điều này. Nhưng gần đây tôi đã hoàn nguyên ứng dụng của mình từ 1.6 đến 1.5.x .. Tôi đã gặp rất nhiều vấn đề với 1.6. – Ved

+0

Tôi cũng sắp hoàn nguyên, đặc biệt là sau khi nhìn thấy câu trả lời bên dưới. Tôi lãng phí hai ngày về điều vô nghĩa này. – Sharondio

Trả lời

16

Điều này đã được sửa với 316f60f và bản sửa lỗi được bao gồm trong v1.6.1 release.

+0

Thảo luận về vấn đề này cũng được chôn trong một vấn đề cũ, không liên quan: https://github.com/angular/angular.js/issues/14631 – Sharondio

+1

Trong 1.6.1, tôi vẫn gặp lỗi này, sử dụng ngResource và $ promise, vì vậy Tôi đã phải sử dụng: $ qProvider.errorOnUnhandledRejections (false); – httpete

+5

@httpete: OP hỏi làm thế nào để có được một lỗi rõ ràng hơn, không phải làm thế nào để ngăn chặn từ chối unhandled (đó không phải là một ý tưởng tốt imo). – gkalpak

0

Tôi gặp vấn đề ngay cả với phiên bản 1.6.1 trong httpErrorInterceptor của tôi, cho một ứng dụng của tôi nếu api của tôi trả lại 404 tôi phải thử một yêu cầu khác với dữ liệu khác ... vì vậy trong trường hợp này tôi chỉ từ chối yêu cầu và góc cạnh vứt bỏ lỗi từ chối không được xử lý ...

Tôi cài đặt 1.5.9 và hiện không còn lỗi nữa!

7

Tôi đã khắc phục sự cố tương tự với phiên bản 1.6.1 bằng cách nâng cấp angular-ui-router thành 0.3.2.

+0

0,4 sửa chữa một số lỗi cũng – Spock

3

Có một trường hợp khác, thêm một handler finally() đến một lời hứa tạo ra các lỗi: http://plnkr.co/edit/eT834BkIEooAMvrVcLDe

finally() tạo ra một lời hứa mới và gọi resolver trên đó.(Từ chối trường hợp thứ 2 trong trường hợp từ chối)

Tôi đã sửa chữa trong plnkr nhưng nó trông không tốt lắm.

+0

Bạn đang phải! Nó im lặng lỗi cho tôi Thx –

3

Tôi nhận được lỗi từ chối không đồng bộ khi lời hứa bị từ chối không được xử lý bởi angular-ui-router (ui-sref) bằng cách sử dụng góc ver1.6.1 & Tính năng này được bật theo mặc định.

Đối với bất cứ ai mà muốn một cách giải quyết (không khuyến khích, mặc dù), bạn có thể trên toàn cầu im lặng unhandled từ chối lời hứa như thế này -

app.config(['$qProvider', function ($qProvider) { $qProvider.errorOnUnhandledRejections(false); }]);

+5

Nó không phải là giải pháp tốt.Tôi đã thử nghiệm nó và trong một số trường hợp thiết lập này sẽ ẩn các lỗi thực sự là tốt –

0

errorOnUnhandledRejections (false); không phải là giải pháp cho tôi.

Bạn thực sự cần xác định trình xử lý ngoại lệ ... tuy nhiên ... hãy bọc nó trong một hàm hết thời gian chờ: điều này sẽ buộc dấu vết gốc/ngăn xếp ban đầu được ném.

Để thực hiện các lỗi hiển thị như một lỗi trong web console, như bạn dự định ban đầu:

ng.factory('$exceptionHandler', function($log) { 
    return function(exception, cause) { 
    // do some some stuff... 
    setTimeout(function(){ 
     // throw the original exception (with correct line #'s etc) 
     throw exception; 
    }) 
    }; 
}); 

Heres lừa timeout: Why can I not throw inside a Promise.catch handler?

0

tôi đã giải quyết được lỗi này bằng cách thêm một mặc định giá trị trong khối catch như:

service.doSomething() 
    .then(function(response) { 
     var x = null; 
     var y = x.y; 
    }).catch(function(error) { 
     var y = 0; 
    }); 

(tính rằng tôi không phải là nhà phát triển góc có kinh nghiệm)

6

tùy chọn đầu tiên chỉ đơn giản là để che giấu một lỗi với disablinconfiguring errorOnUnhandledRejections trong $ qProvider configuratio như đề xuất Cengkuru Michael:

app.config(['$qProvider', function ($qProvider) { 
    $qProvider.errorOnUnhandledRejections(false); 
}]); 

NHƯNG này sẽ chỉ tắt ghi nhật ký. Các lỗi bản thân sẽ vẫn

các giải pháp tốt hơn trong trường hợp này sẽ - xử lý một sự từ chối với .catch() phương pháp:

service.doSomething() 
    .then(function (response) {}) 
    .catch(function (err) {}); 

Liên kết hữu ích:

+0

Làm việc cho tôi :) – yashpandey

2

Thông tin này giúp tôi theo dõi những gì (trong trường hợp của tôi) đã tạo ra lời hứa và không thêm trình xử lý lỗi. Tôi thấy nó bị chôn vùi trong cuộc thảo luận về vấn đề #2889 "Possibly unhandled rejection with Angular 1.5.9".

Gợi ý, là, vá $q để lưu vào bộ nhớ cache ngăn xếp dấu vết khi tạo lời hứa, sao cho nó có thể được truy xuất khi lỗi được kích hoạt.

Để làm điều đó, chèn mã này để trang trí $q nơi nào đó gần phía trên cùng của ứng dụng góc của bạn:

// Decorate the $q service when app starts 
app.decorator('$q', ["$delegate", function($delegate) { 
    // Create a new promise object 
    var promise = $delegate.when(); 

    // Access the `Promise` prototype (nonstandard, but works in Chrome) 
    var proto = promise.__proto__; 

    // Define a setter for `$$state` that creates a stacktrace 
    // (string) and assigns it as a property of the internal `$$state` object. 
    Object.defineProperty(proto, '$$state', { 
    enumerable: true, 
    set: function(val) { 
     val.stack = new Error().stack; 
     this._$$state = val; 
    }, 
    get: function() { 
     return this._$$state; 
    } 
    }); 

    return $delegate; 
}]); 

Sau đó tìm kiếm các mã góc cho thông báo "có thể không được quản lý từ chối" và đặt một breakpoint trên dòng đó . Khi breakpoint được đạt tới, in ra giá trị của toCheck.stack trên bàn điều khiển, và bạn sẽ thấy một cái gì đó như thế này:

>> toCheck.stack 
"[email protected]://localhost:8000/js/dual-site.js:18:19 
[email protected]://localhost:8000/js/angular.js:17008:22 
[email protected]://localhost:8000/js/angular.js:17016:20 
[email protected]://localhost:8000/js/angular.js:17026:14 
[email protected]://localhost:8000/js/angular-state-machine.js:436:24 
StateMachine/[email protected]://localhost:8000/js/angular-state-machine.js:235:16 

Các mã vi phạm là khung gọi góc của catch/sau đó chức năng.

+0

Điều này nên là câu trả lời đúng, và điều này nên là một phần của Angular. Cảm ơn rất nhiều!! – ZadrackSaria

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