I recently upgraded from Bluebird 3.5.5 to 3.7.0, which happens to pull in the unhandled rejection handling from https://github.com/petkaantonov/bluebird/commit/60ef7a0e23fd320a11281f67c64a39ff95612ce9 (first added in 3.6.0).
The path which adds an iframe, grabs setTimeout from it, then removes it from the document does not appear to work in Firefox 71. Instead, calling this setTimeout fails with an NS_ERROR_NOT_INITIALIZED exception.
(As an aside, I am curious why you want to pull setTimeout from a throwaway frame like this... Why not just use the main document?)
For now, I will revert back to 3.5.5.
I'm also experiencing this with version 3.7.0.
huh I had no idea firefox does this
@jryans @schleumer can you please try 3.7.1 ?
The issue still appears in 3.7.1 as well, which makes sense to me, as it still runs the problematic iframe approach.
I'm having the same issue in 3.7.1 and have to downgrade to 3.5.5 for now.
As described here, Bluebird creates an iframe, takes its setTimeout function and then removes the iframe from the DOM. It then uses that function to schedule checks for unhandled rejections.
I suspect that Firefox destroys the window of the iframe when it's removed from the DOM, and as such the setTimeout function becomes invalid.
Can't we capture the original value of setTimeout while Bluebird is loading, and always use that inside deferUnhandledRejectionCheck? That way, Bluebird would not be affected by a test framework replacing the global setTimeout afterwards. It would also be much simpler, without needing platform-specific specializations.
The result of this bug is that the error NS_ERROR_NOT_INITIALIZED occurs whenever I reject a Promise. This error covers up the rejection reason I provide, resulting in incorrect behavior and obscuring the error I actually care about.
@benjamingr
huh I had no idea firefox does this
This seems consistent enough with the HTML spec (which I am not familiar with but am trying to check this against, sorry for any misinterpretation).
When an
iframeelement is removed from a document, the user agent must discard the element's nested browsing context, if it is not null, and then set the element's nested browsing context to null.
The nested browsing context is what is returned by HTMLIFrameElement.contentWindow which is where setTimeout() is being grabbed from in this case. I don鈥檛 know if setTimeout() from a nested browsing context is supposed to somehow refer to the top-level browsing context鈥檚 setTimeout(). Let me know if I am missing something鈥攐therwise, I would tend to think this to be a bluebird bug (and not a Mozilla bug).
I was experiencing this bug as well and the newly released version 3.7.2 fixed it for me.
Yes, https://github.com/petkaantonov/bluebird/commit/f88044507cb5ad8a3a27b219c7ea4e5a2d1e7207 should indeed fix the issue, thanks!
Most helpful comment
As described here, Bluebird creates an
iframe, takes itssetTimeoutfunction and then removes theiframefrom the DOM. It then uses that function to schedule checks for unhandled rejections.I suspect that Firefox destroys the window of the
iframewhen it's removed from the DOM, and as such thesetTimeoutfunction becomes invalid.Can't we capture the original value of
setTimeoutwhile Bluebird is loading, and always use that insidedeferUnhandledRejectionCheck? That way, Bluebird would not be affected by a test framework replacing the globalsetTimeoutafterwards. It would also be much simpler, without needing platform-specific specializations.