Possibly unhandled rejection in Angular 1.6
Solution 1
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.
Solution 2
First option simply is to hide this specific rejection error by setting errorOnUnhandledRejections
in $qProvider configuration 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:
Solution 3
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.
Solution 4
I fixed the same problem with version 1.6.1 by upgrading angular-ui-router to 0.3.2.
Solution 5
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.
Piotr Pradzynski
software developer @ prondzyn.com blogger @ ProgramistaNaSwoim.pl Toruń JUG co-founder and former co-leader Toruń JUG Day originator and coordinator @prondzyn on Twitter
Updated on August 14, 2020Comments
-
Piotr Pradzynski almost 4 years
I have a code with AngularJS:
service.doSomething() .then(function(result) { //do something with the result });
In AngularJS 1.5.9 when I have error in the
.then()
section like:service.doSomething() .then(function(result) { var x = null; var y = x.y; //do something with the result });
I'm getting clear error message:
TypeError: Cannot read property 'y' of null
But in version 1.6 with the same code I'm getting a different error:
Possibly unhandled rejection: {} undefined
I know that this is related to this change, and the single solution is quite simple by adding
.catch()
block:service.doSomething() .then(function(result) { var x = null; var y = x.y; //do something with the result }) .catch(console.error);
Now I again have what I want:
TypeError: Cannot read property 'y' of null
But how to obtain the same result (more detailed error) for entire application without adding
.catch()
block in every single place?I tested the suggested solution to disable this by adding:
$qProvider.errorOnUnhandledRejections(false);
But with this the situation is even worse - I do not have ANYTHING in the console! The error is swallowed somewhere and not logged at all. I'm not sure is it a problem with AngularJS 1.6 or with my configuration.
Do you have any ideas how to "restore" logging behavior from version 1.5.9?
EDIT:
Adding custom error handler:
.factory('$exceptionHandler', function($log) { return function(exception, cause) { $log.warn(exception, cause); }; })
does not help at all. In the error handler I already receive the "wrapped" error.
-
Sharondio over 7 yearsDiscussion on this also buried in an old, unrelated issue: github.com/angular/angular.js/issues/14631
-
httpete over 7 yearsIn 1.6.1, I was still getting this error, using ngResource and $promise, so I had to use: $qProvider.errorOnUnhandledRejections(false);
-
gkalpak over 7 years@httpete: OP asked how to get a more clear error, not how to suppress unhandled rejections (which is not a good idea imo).
-
Rouche over 7 yearsWell, i am with 1.6.1 and i still get the error. Even if i do have an error callback. Problem is my callback need to return a rejected promise so the client knows the service have an error. Then Poof! $http(config).then( (response) => {...}, (error) => { return $q.reject(error); } );
-
gkalpak over 7 yearsIf you don't handle a rejection, you get an error. That's how it works. (Note that each
then()
call returns a new promise.) -
Rouche over 7 yearsWell, this means i have to do same thing as @httpete, or its a no go sadly :(. We have an interceptor wich deals with unhandled promises so that we dont need to do the same code everywhere.
-
Piotr Pradzynski over 7 yearsIt is not good solution. I tested it and in some situations this setting will hide the true error as well.
-
Spock over 7 years0.4 fixes some bugs also.
-
Admin over 6 yearsThis should be the right answer, and this should be part of Angular. Thanks a lot!!
-
Mawg says reinstate Monica about 4 yearsI get this error when moving from 1.5 to 1.7, and I do not have any (explicit) promises in my code. It functions perfectly in 1.5, but throws that error 3 times on starting in 1.7