-
Notifications
You must be signed in to change notification settings - Fork 94
fix: premount loader race condition #896
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
758b6dd
to
080eb7b
Compare
src/Payments/PreMountLoader.res
Outdated
@@ -12,30 +12,36 @@ let sendPromiseData = (promise, key) => { | |||
|
|||
let useMessageHandler = getPromisesAndHandler => { | |||
React.useEffect(_ => { | |||
let (promises, messageHandler) = getPromisesAndHandler() | |||
let messageHandler = getPromisesAndHandler() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This variable used to be called getPromisesAndHandler
because it used to return promise and message handler. if that is changed to only return handler, then can we rename the function to reflect that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed the name
src/hyper-loader/Elements.res
Outdated
fetchPaymentsList(mountedIframeRef, componentType) | ||
let paymentMethodsPromise = Promise.make((resolve, _) => { | ||
fetchPaymentsList(mountedIframeRef, componentType, resolve) | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we have to wrap fetchPaymentsList
by Promise.make((resolve, _) =. {}
? Why can't fetchPaymentsList
return a promise on its own and resolve that promise when it wants
Wrapping with Promise.make and passing the resolve function seems unnecessary - adding a lot of responsibility on the function caller. It might be simpler if the function returns promise by itself
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved Promise inside the function
fetchSavedPaymentMethods(mountedIframeRef, false, componentType) | ||
Promise.make((resolve, _) => { | ||
fetchSavedPaymentMethods(mountedIframeRef, false, componentType, resolve) | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same over here as well. Can fetchSavedPaymentMethods
return promise instead of the caller having to do Promise.make and pass resolve function down as arg?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
moved the promise inside here as well
## [0.114.2](v0.114.1...v0.114.2) (2025-02-18) ### Bug Fixes * premount loader race condition ([#896](#896)) ([7c8f1df](7c8f1df))
Type of Change
Description
Hyperswitch Web creates an invisible iframe (Pre Mount Loader) to make API calls for fetching payment methods, customer saved payment methods, and session tokens. The top-level page retrieves these responses via post messages. The iframe includes a cleanup function that waits for all API calls to complete before unmounting itself by sending a post message to the top level.
However, a race condition occurred where the iframe would receive all API responses but unmount before the top level had retrieved them, as the post messages to fetch these responses had not yet been triggered. This led to lost API responses.
To fix this, the iframe now unmounts only after all responses have been successfully received at the top level.
How did you test it?
Test whether SDK is rendering properly with correct data in different browsers with varied network throttling conditions
TrustPay ApplePay also needs to be tested
Checklist
npm run re:build