Nested setTimeout calls cause invalid Promise unhandled rejection message
loganfsmyth opened this issue · comments
Came across this when upgrading to Babel 5, picking up core-js 0.9.18, causing us to switch from Chrome promises to polyfilled promises.
There appears to be some very strange setTimeout
/postMessage
nesting behavior. I'm seeing
setTimeout(function(){
setTimeout(function(){
setTimeout(function(){
setTimeout(function(){
Promise.reject('err').then(function(){}).then(function(){}).catch(function(err){
console.log('handled error', err);
});
}, 0);
}, 500);
}, 0);
}, 500);
in Chrome print out BOTH my own console.log('handled error');
AND the internal console.error('Unhandled promise rejection');
message. It seems to be somewhat flaky, and it almost always works when the devtools are open, but if you run that code in a standalone file with just core-js, and open devtools after running it, you'll see the error.
Obviously this code is really roundabout, but this came up for me in Jasmine because of code like
waits(500);
waits(500);
runs(function(){
// Some normal code that happens to create a promise chain like the one above.
});
I did some testing on my own machine by splitting out the core-js code and just using straight JS:
setTimeout(function(){
setTimeout(function(){
setTimeout(function(){
setTimeout(function(){
setTimeout(function(){
console.log('2')
}, 1);
window.addEventListener('message', function fn(){
window.removeEventListener('message', fn, false);
console.log('1');
setTimeout(function(){
console.log('3');
}, 1);
}, false);
window.postMessage('something', '*');
}, 0);
}, 500);
}, 0);
}, 500);
prints
1
3
2
when I have devtools closed, which I think is making the promise code process the rejection in the wrong order.