Angular 1.6.0:“可能未处理的拒绝”错误

我们有一个模式来解决我们的Angular应用程序中的承诺,直到Angular 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); }); 

以下是我们如何触发Karma中的错误:

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

现在,随着1.6.0的更新,Angular在我们的unit testing(Karma)中突然抱怨拒绝的承诺,并且出现了“可能未处理的拒绝”的错误。 但是,我们正在处理拒绝的第二个函数,调用我们的错误服务。

Angular在这里寻找什么? 它如何要我们“处理”拒绝?

尝试添加到您的configuration。 我有一个类似的是一次,这个解决方法做了伎俩。

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

通过回滚到Angular 1.5.9来find问题并重新运行testing。 这是一个简单的注入问题,但Angular 1.6.0通过抛出“可能未处理的拒绝”错误来代替这个错误,从而混淆了实际的错误。

您所显示的代码将处理在发送给.then之前发生的拒绝。 在这种情况下,你传给你的第二个回叫将被调用,并被拒绝处理。

但是 ,当您呼叫的承诺成功时,它会调用第一个回叫。 如果这个callback抛出一个exception或返回一个被拒绝的promise,这个结果的拒绝将不会被处理 ,因为第二个callback没有处理第一个原因造成的拒绝。 这就是遵守Promise / A +规范的承诺实现是如何工作的,而且Angular承诺是合规的。

你可以用下面的代码来说明这一点:

 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"))); 

如果你在Node中运行它,它也符合Promises / 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 

第一个选项只是通过在$ qProviderconfiguration中configurationerrorOnUnhandledRejections来禁用错误来隐藏错误Cengkuru Michael

但这只会closures日志。 错误本身将保持

在这种情况下更好的解决scheme将是 – 使用.catch(fn)方法处理拒绝:

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

链接:

  • 诺言
  • angular度:
    • 将Angular 1.5移植到1.6
    • $ http:删除不推荐的callback方法:'success()/ error()'

请在这里查看答案:

在Angular 1.6中可能没有处理的拒绝

看起来应该在版本1.6.1中修复

我在testing执行过程中观察到相同的行为。 奇怪的是,在生产代码工作正常,只有在testing失败。

简单的解决scheme,使您的testing快乐是添加catch(angular.noop)到您的承诺模拟。 在上面的例子中,应该看起来像这样:

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

您可以通过closureserrorOnUnhandledRejections来掩盖问题,但是错误表示您需要“处理可能的拒绝”,因此您只需要在承诺中添加一个catch。

 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