Possibly unhandled rejection in Angular 1.6

半世苍凉 提交于 2019-11-29 02:52:33
gkalpak

This has been fixed with fix($q): Add traceback to unhandled promise rejections -- Commit 316f60f and the fix is included in the v1.6.1 release.

First option is simply to hide an error with disablinconfiguring errorOnUnhandledRejections in $qProvider configuratio as suggested Cengkuru Michael:

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

BUT this will only switch off logging. The error itself will remain

The better solution in this case will be - handling a rejection with .catch() method:

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

Useful Links:

I fixed the same problem with version 1.6.1 by upgrading angular-ui-router to 0.3.2.

This information helped me to track down what (in my case) was creating the promise and not adding an error handler. I found it buried in the discussion of issue #2889 "Possibly unhandled rejection with Angular 1.5.9".

The gist, is, patch $q to cache a stack-trace on creating promises, such that it can be retrieved when the error is triggered.

To do it, insert this code to decorate $q somewhere near the top of your angular app:

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

Then search the angular code for the message "possibly unhandled rejection" and put a breakpoint on that line. When the breakpoint is reached, print out the value of toCheck.stack on the console, and you'll see something like this:

>> toCheck.stack
"set@http://localhost:8000/js/dual-site.js:18:19
Promise@http://localhost:8000/js/angular.js:17008:22
then@http://localhost:8000/js/angular.js:17016:20
catch@http://localhost:8000/js/angular.js:17026:14
SyncStrategy.prototype.send@http://localhost:8000/js/angular-state-machine.js:436:24
StateMachine/this.send@http://localhost:8000/js/angular-state-machine.js:235:16

The offending code is the frame calling angular's catch/then functions.

There is another case, adding a finally() handler to a promise generate the error: http://plnkr.co/edit/eT834BkIEooAMvrVcLDe

Because finally() creates a new promise and call the resolver on it. (Rejecting a 2nd one in a rejection case)

Ive put a fix in the plnkr but it doesn't look very good.

I got same unhandled rejection error when a rejected promise is not handled by angular-ui-router (ui-sref) using angular ver1.6.1 & This feature is enabled by default.

For anyone that wants a workaround (not recommended, though), you can globally silence unhandled promise rejections like this —

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

I have solved this error by adding a default value in the catch block like:

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

(take in count that I am not an experienced angular developer)

I have the problem even with version 1.6.1 in my httpErrorInterceptor, for one usecase my if my api return 404 i have to try another request with other data... so in this case i only reject the request and angular throw the unhandled rejection error...

I install 1.5.9 and now there is no more error !

nawlbergs

errorOnUnhandledRejections(false); was not a resolution for me.

You do indeed need to define an exception handler... however... wrap it in a timeout function: this will force the original exception/stack trace to be thrown.

To make the error show up as an error in the web console, as you originally intended:

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 the timeout trick: Why can I not throw inside a Promise.catch handler?

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!