19

У меня есть код с AngularJS:Возможно необработанное отказ в угловом 1.6

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

В AngularJS 1.5.9, когда у меня есть ошибки в .then() разделе как:

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

Я получаю ясно сообщение об ошибке:

TypeError: Cannot read property 'y' of null

Но в версии 1.6 с таким же кодом у меня есть другая ошибка:

Possibly unhandled rejection: {} undefined

Я знаю, что это связано с this change, и единственным решением является довольно простым добавлением .catch() блок:

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

Теперь я снова иметь то, что я хочу:

TypeError: Cannot read property 'y' of null

Но как получить тот же результат (более подробную ошибку) для всего приложения без добавления блока .catch() в каждом отдельном месте?

Я протестировал предложенное решение отключить, добавив:

$qProvider.errorOnUnhandledRejections(false); 

Но с этим ситуация еще хуже - у меня нет НИЧЕГО в консоли! Ошибка проглатывается где-то и вообще не регистрируется. Я не уверен, что это проблема с AngularJS 1.6 или с моей конфигурацией.

Есть ли у вас какие-либо идеи о том, как «восстановить» поведение ведения журнала из версии 1.5.9?

EDIT:

Добавление пользовательского обработчика ошибок:

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

не поможет. В обработчике ошибок я уже получил «завернутую» ошибку.

+1

Понятия не имею. Но я недавно вернул свое приложение с 1.6 до 1.5.x .. У меня было много проблем с 1.6. – Ved

+0

Я тоже вернусь, особенно после просмотра ответа ниже. Я потратил два дня на эту ерунду. – Sharondio

ответ

16

Это было исправлено с помощью 316f60f, а исправление включено в комплект поставки v1.6.1 release.

+0

Обсуждение этого также было похоронено в старой, не связанной с этим проблеме: https://github.com/angular/angular.js/issues/14631 – Sharondio

+1

В 1.6.1 я все еще получал эту ошибку, используя ngResource и $ prom, поэтому Мне пришлось использовать: $ qProvider.errorOnUnhandledRejections (false); – httpete

+5

@httpete: ОП спросил, как получить более явную ошибку, а не как подавить необработанные отказы (что не очень хорошая идея imo). – gkalpak

0

У меня проблема даже с версией 1.6.1 в моем httpErrorInterceptor, для одного usecase my, если мой api return 404 мне нужно попробовать другой запрос с другими данными ... так что в этом случае я только отклоняю запрос и угловой выбросить необработанную ошибку отклонения ...

Я устанавливаю 1.5.9, и теперь больше нет ошибок!

7

Я исправил ту же проблему с версией 1.6.1, обновив угловое ui-router до 0.3.2.

+0

0.4 исправляет некоторые ошибки. – Spock

3

Существует еще один случай, добавив finally() обработчика обещания генерировать ошибку: http://plnkr.co/edit/eT834BkIEooAMvrVcLDe

Поскольку finally() создает новое обещание и вызвать распознаватель на него.(Отклонение второго в случае отказа)

Ive положил исправление в plnkr, но оно выглядит не очень хорошо.

+0

Вы правы! Это заставило меня заблудиться! Thx. –

3

Я получил такую ​​же необработанную ошибку отклонения, когда отклоненное обещание не обрабатывается угловым ui-router (ui-sref) с использованием углового ver1.6.1 & Эта функция включена по умолчанию.

Для тех, кто хочет обходной путь (не рекомендуется, хотя), может быть глобальным молчание необработанного обещания отбраковки, как это -

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

+5

Это нехорошее решение. Я протестировал его, и в некоторых ситуациях этот параметр будет скрыть истинную ошибку. –

0

errorOnUnhandledRejections (ложь); для меня не было решением.

Вам действительно нужно определить обработчик исключений ... однако ... оберните его в функцию тайм-аута: это заставит бросать исходную трассировку исключения/стека.

Для того, чтобы ошибка появляется как ошибка в веб-консоли, как вы первоначально предполагалось:

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 таймаут трюк: Why can I not throw inside a Promise.catch handler?

0

Я решил эту ошибку, добавив по умолчанию значение в блоке поймать как:

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

(взять в счете, что я не опытный угловой разработчик)

6

Первый вариант просто, чтобы скрыть ошибку с disablinconfiguring errorOnUnhandledRejections в $ qProvider configuratio как предложено Cengkuru Michael:

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

НО это будет только отключить ведение журнала. Сама ошибка будет оставаться

лучшим решением в этом случае будет - обработка отказа с .catch() методом:

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

Полезных ссылок:

+0

Работал для меня :) – yashpandey

2

Эта информация помогла мне отследить, что (в моем случае) создавало обещание и не добавляло обработчик ошибок. Я нашел его похороненным в обсуждении вопроса #2889 "Possibly unhandled rejection with Angular 1.5.9".

Суть заключается в патче $q для кэширования трассировки стека при создании обещаний, чтобы его можно было получить при срабатывании ошибки.

Чтобы сделать это, вставьте этот код, чтобы украсить $q где-то в верхней части углового приложения:

// 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; 
}]); 

Тогда поиск углового кода для сообщения «возможно, необработанная отбраковка» и поставить точку останова на эту линии , Когда достигаются точка останова, распечатайте значения toCheck.stack на консоли, и вы увидите что-то вроде этого:

>> 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 

Нарушитель кода является кадром вызова угловатого улова/затем функции.

+0

Это должен быть правильный ответ, и это должно быть частью Углового. Большое спасибо!! – ZadrackSaria