braintree / braintree-web

A suite of tools for integrating Braintree in the browser
https://developer.paypal.com/braintree/docs/start/hello-client/javascript/v3
MIT License
444 stars 134 forks source link

Mutiple calls to UnionPay fetchCapabilities - only 1 resolves #441

Closed chmac closed 5 years ago

chmac commented 5 years ago

General information

Issue description

Here's a very simple reproduction:

        console.log("fetchUnionPayCardCapabilities #6214Nh");
        unionPayInstance
            .fetchCapabilities({
                hostedFields: hostedFieldsInstance,
            })
            .then(result => {
                console.log("fetchUnionPayCardCapabilities result 1 #aGlvAx");
            });
        unionPayInstance
            .fetchCapabilities({
                hostedFields: hostedFieldsInstance,
            })
            .then(result => {
                console.log("fetchUnionPayCardCapabilities result 2 #aGlvAx");
            });

The result 2 never happens. That promise never resolves.

I discovered this because we were using the blur hook to run the fetchCapabilities call. However, when clicking directly on our submit button after entering the card number, the blur hook happens after the submit event. I realise it's an odd edge case but figured I'd report the bug anyway. We'll solve it by wrapping the call to ensure we only have 1 request in flight at any time.

chmac commented 5 years ago

To add a little more context, it seems like this issue only exists for the first request. If I add a call to await fetchCapabilities() which is before the code above, then both result 1 and result 2 are logged, and I see 2 network requests to the capabilities endpoint in the Network tab. But if I make a second request while the first ever request is in flight, it seems that the promise never resolves.

I've tried making 4 requests, and so long as the first one completes before any other start, they will all succeed. But any requests which are attempted while the 1st is in flight seem to silently fail.

crookedneighbor commented 5 years ago

Thanks for the report.

I imagine there's some race condition happening with creating the hosted fields bridge frame: https://github.com/braintree/braintree-web/blob/acf72b8611a698c6159958e0e02044d81c95f6e9/src/unionpay/shared/unionpay.js#L363

Since the bus does exist, but the frame has not actually been created yet

crookedneighbor commented 5 years ago

This is fixed in 3.47.0.