Bluebird: Unhandled rejection check causes errors in Firefox

Created on 16 Oct 2019  路  10Comments  路  Source: petkaantonov/bluebird

  • Bluebird 3.7.0
  • Firefox 71 (Nightly)

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.

Most helpful comment

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.

All 10 comments

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).

iframe spec removal:

When an iframe element 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.

Was this page helpful?
0 / 5 - 0 ratings