statsig-io / js-client

Statsig's SDK for client-side javascript applications.
ISC License
17 stars 11 forks source link

Prefetch timeouts result in unhandle promise rejection #17

Closed sethhitch closed 6 months ago

sethhitch commented 1 year ago

We've recently incorporated the Statsig JavaScript client into our web application. While developing locally today, I found that Chrome continuously paused the execution of the application because I had "Pause on uncaught exceptions" enabled in DevTools, and the Statsig SDK was timing out while attempting to prefetch data during initialization. This doesn't interrupt the functionality of our product, but does degrade the developer experience.

As I understand your PromiseWithTimout type, the timeout is actually being handled, so perhaps this is just a case of the Chrome DevTools not being aware of that?

Screenshot 2023-08-22 at 3 02 15 PM

tore-statsig commented 1 year ago

Thanks for the report. This rejection should be handled as you noted, but we can look into if handling it differently would make chrome dev tools happy with it. Which prefetch are you referring to? And which SDK version did you experience this on? Want to make sure we have the right information to reproduce.

sethhitch commented 1 year ago

This is happening during my call to initialize. DevTools pauses 8 times during this process.

            var user = {
                userID: this.userID,
            };
            var opts = {
                disableCurrentPageLogging: true,
                disableErrorLogging: true,
                disableAutoMetricsLogging: true,
            };
            var clientSDKKey = "blah";
            this.statsig.initialize(clientSDKKey, user, opts);

We're using https://cdn.jsdelivr.net/npm/statsig-js@4.39.0/build/statsig-prod-web-sdk.min.js

daniel-statsig commented 1 year ago

This appears to be chrome getting confused. This rejection is caught further up in the call stack. I am concerned that you are seeing it more than once though. Are you able to share a snippet that hits the the timeout 8 times? Also worrying is that the screenshot states that it hit a timeout after 30 seconds, is this something you are seeing in production, or just your local testing?

sethhitch commented 1 year ago

The code snippet above (simply calling initialize) results in hitting the timeout multiple times. I actually see this in production at this point, too. However, looking at the network inspector, nothing is actually timing out - so that's good!

I think this happens because StatsigNetwork.postWithTimeout sets a timeout but never clears it, so the timeout will always fire.

https://github.com/statsig-io/js-client/blob/50ac1d8bde4cfb7d71581ef80ac1c8f1259c9288/src/StatsigNetwork.ts#L120-L127

This doesn't do any harm - in normal operation, the timer promise rejection is ignored because the fetchPromise has already resolved and thus won the race.

https://github.com/statsig-io/js-client/blob/50ac1d8bde4cfb7d71581ef80ac1c8f1259c9288/src/StatsigNetwork.ts#L197-L200

xinlili-statsig commented 6 months ago

Fix has been released with https://github.com/statsig-io/js-client/releases/tag/4.50.2