angular / zone.js

Implements Zones for JavaScript
https://github.com/angular/angular/tree/master/packages/zone.js/
MIT License
3.25k stars 408 forks source link

macroTask 'setInterval': can not transition to 'running', expecting state 'scheduled', was 'notScheduled' #1167

Closed FDIM closed 5 years ago

FDIM commented 5 years ago

So for quite some time we are seeing this error message in our logs and none of us are able to reproduce it locally. Does any one know how/why this case could occur?

message:     macroTask 'setInterval': can not transition to 'running', expecting state 'scheduled', was 'notScheduled'. 
stack:   Error: macroTask 'setInterval': can not transition to 'running', expecting state 'scheduled', was 'notScheduled'.
   at e.prototype._transitionTo (<url>/polyfills.77d3c168854bf6cfdbd7.js:1:10272)
   at e.prototype.runTask (<url>/polyfills.77d3c168854bf6cfdbd7.js:1:3773)
   at e.invokeTask (<url>/polyfills.77d3c168854bf6cfdbd7.js:1:9840)
   at invoke (<url>/polyfills.77d3c168854bf6cfdbd7.js:1:9738)
   at n.args[0] (<url>/polyfills.77d3c168854bf6cfdbd7.js:1:25135)   

We are seeing it for setTimeout and for setInterval and it is happening only in IE 11. What is interesting is that right before this error I can see $digest in progress errors (we run Angular + angularjs hybrid) from 4 http requests which already tells me that something fairly weird is happening. E.g. seems like callback passed to browser.defer is called multiple times.

The only way I could get something similar is that if I modify setTimeout / setInterval and call the callback twice, but it gets triggered only few times and then stops.

The most annoying fact is that once this edge case is hit, that specific user will get an error every 0.5s (varies) until browser is refreshed. We have 200k events like this from 4 different users in last 7 days.

JiaLiPassion commented 5 years ago

Is that possible to provide a reproduce repo? Thanks! And this should be fixed here https://github.com/angular/zone.js/pull/1156, but I can not reproduce the issue, so if you can provide some reproduce repo, that will help to find the real reason.

FDIM commented 5 years ago

Unfortunately not, at least not in a normal scenario - we only see it client log many times and can trace it back to the first deployment of the hybrid app (when we started using angular / zone.js)

I did manage to break it, but only if I patch setTimeout / setInterval like this:

var orgSetTimeout = setTimeout;
window.setTimeout = function(fn, delay) {
    var id = orgSetTimeout.call(this, function () {
        fn();
        clearTimeout(id);
        fn();
    }, delay);
    return id;
};

The good thing is that #1156 fixes it and the error is no longer thrown. So my only idea is that IE might fire the callback, even if it was cancelled in certain scenarios - maybe under heavy load?

JiaLiPassion commented 5 years ago

Yeah, thanks, just like you said, maybe some bug in IE cause the callback fired even it is cancelled...

JiaLiPassion commented 5 years ago

will close for now, it should be fixed by #1156

FDIM commented 5 years ago

It did fix the issue - we no longer see this error in the logs. Thanks!