50

У нас есть образец для решения обещания в нашем угловом приложении, которое служит нам хорошо вплоть до угловых 1.6.0:Угловая 1.6.0: ошибка «Возможно, необработанное отказ»

resource.get().$promise 
     .then(function (response) { 
     // do something with the response 
     }, function (error) { 
      // pass the error the the error service 
      return errorService.handleError(error); 
     }); 

А вот как мы вызывая ошибку в карму:

resourceMock.get = function() { 
     var deferred = $q.defer(); 
     deferred.reject(error); 
     return { $promise: deferred.promise }; 
    }; 

Теперь, с обновлением до 1.6.0, Угловое внезапно жалуется на наших модульных тестов (в карму) для отклоненных обещаний с ошибкой «Возможно, необработанное отказа». Но мы обрабатываем отказ во второй функции, которая вызывает нашу службу ошибок.

Что именно Angular ищет здесь? Как он хочет, чтобы мы «отреагировали» на отказ?

+1

Я заметил это и в нашей базе кода. Как ни странно, запуск комплекта с помощью хромированной пусковой установки отлично работает. PhantomJS жалуется. –

+0

Если вы получили это и не просто обновили, вот как вы можете проверить свою угловую версию: http://stackoverflow.com/questions/16017699/how-can-i-check-which-version-of-angular- im-using – hubatish

ответ

55

Попробуйте добавить этот код в свой конфиг. Однажды у меня была подобная проблема, и этот обходной ход сделал трюк.

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

Я должен указать, что это просто скрывает ошибку, согласно разработчикам, есть некоторая проблема в коде, и она просто маскирует ошибку. –

+0

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

+0

@SachinSharma вам все рассказал –

17

Код, который вы покажете, будет обрабатывать отклонение, которое происходит до вызова .then. В такой ситуации будет вызываться второй обратный вызов, который вы перейдете на .then, и отказ будет обработан.

Однако, когда обещание, по которому вы звоните .then, успешно, оно вызывает 1-й обратный вызов. Если этот обратный вызов генерирует исключение или возвращает отклоненное обещание, это отклонение не будет обрабатываться, так как второй обратный вызов не обрабатывает отклонения по причине 1-го. Это как раз то, как обещают реализации, соответствующие спецификациям Promises/A+, и Угловые обещания совместимы.

Вы можете проиллюстрировать с помощью следующего кода:

function handle(p) { 
    p.then(
     () => { 
      // This is never caught. 
      throw new Error("bar"); 
     }, 
     (err) => { 
      console.log("rejected with", err); 
     }); 
} 

handle(Promise.resolve(1)); 
// We do catch this rejection. 
handle(Promise.reject(new Error("foo"))); 

Если вы запустите его в узел, который также соответствует обещаниям/A +, вы получите:

rejected with Error: foo 
    at Object.<anonymous> (/tmp/t10/test.js:12:23) 
    at Module._compile (module.js:570:32) 
    at Object.Module._extensions..js (module.js:579:10) 
    at Module.load (module.js:487:32) 
    at tryModuleLoad (module.js:446:12) 
    at Function.Module._load (module.js:438:3) 
    at Module.runMain (module.js:604:10) 
    at run (bootstrap_node.js:394:7) 
    at startup (bootstrap_node.js:149:9) 
    at bootstrap_node.js:509:3 
(node:17426) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): Error: bar 
+0

Хорошие очки! Да, цель состоит в том, чтобы обработать отклонение, которое происходит до вызова. Then. Код, который вызывает это отклонение (и который работал для Angular 1.5.9), был добавлен в исходный вопрос. – Groucho

+1

Как на самом деле исправить заданный код шаблона? – vip

+4

Хорошо, исправление похоже на $ prom.then (success) .catch (ошибка), где catch улавливает все ошибки, больше в разделе «Примечание» в [migration] (https://docs.angularjs.org/guide/migration# migrate1.5to1.6-ng-services- $ http) – vip

16

Найдено вопрос прокаткой вернуться к Угловому 1.5.9 и повторить тест. Это была простая проблема с инжектором, но Angular 1.6.0 заменил это, выбросив вместо этого ошибку «Возможно необработанное отклонение», запутывая фактическую ошибку.

+0

Это большая проблема для меня в настоящее время, когда я переношу базу кода и заменяю старую вложенную зависимость. Вы нашли способ предотвратить эту обфускацию и заставить ее бросить реальную ошибку? – ChristopherJ

+0

Верхний ответ выше будет исправлять его в запущенном коде, но я не мог заставить его выбросить ошибку в Карме, не откатываясь назад до Углового 1.5.9. – Groucho

2

Я наблюдал такое же поведение во время выполнения теста. Странно, что на производственный код работает нормально и терпит неудачу только на тестах.

Простым решением, чтобы ваши испытания были счастливыми, - это добавить catch(angular.noop) к вашему обещанию. В случае примера выше это должно выглядеть следующим образом:

resourceMock.get = function() { 
 
    var deferred = $q.defer(); 
 
    deferred.reject(error); 
 
    return { $promise: deferred.promise.catch(angular.noop) }; 
 
};

4

Пожалуйста, проверьте ответ здесь:

Possibly unhandled rejection in Angular 1.6

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

+0

Все еще получаю это в 1.6.2 – ACIDSTEALTH

+0

Хотя эта ссылка может ответить на вопрос, лучше включить здесь основные части ответа и предоставить ссылку для справки. Ответные ссылки могут стать недействительными, если связанная страница изменится.- [Из обзора] (/ review/low-quality-posts/18725685) –

+0

@ MostafaTorbjørnBerg спасибо. Я обновил ответ. –

2

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

resource.get().$promise 
    .then(function (response) { 
    // do something with the response 
    }).catch(function (error)) { 
     // pass the error the the error service 
     return errorService.handleError(error); 
    }); 

Ссылка: https://github.com/angular-ui/ui-router/issues/2889

+1

это на самом деле лучший ответ. вы не должны маскировать возможную ошибку – Ero

10

Первый вариант просто скрыть ошибку при отключении его настройки errorOnUnhandledRejections в конфигурации $ qProvider как предложено Cengkuru Michael

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

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

resource.get().$promise 
    .then(function (response) {}) 
    .catch(function (err) {}); 

ССЫЛКИ:

0

Это не может быть ваша speficic ситуация, но у меня была похожая проблема.

В моем случае я использовал angular-i18n и асинхронно получал словарь locale. Проблема заключалась в том, что json-файл, который он получал, был неправильно отступом (смешивание пробелов и вкладок). Запрос GET не прошел.

Коррекция отступа решена.

Смежные вопросы