Skip to content

Conversation

@bc-dronov
Copy link
Contributor

@bc-dronov bc-dronov commented Nov 27, 2025

What/Why?

Block strategy de-initialization while pressing the 'Pay' button on the Google pay payment sheet.
We need this because of make sure we don't have any side-effects during the moment between clicking 'Pay' and loading all the necessary data. Otherwise we will receive an error.

Rollout/Rollback

Revert this PR.

Testing

Manual testing.
Before:

Before.mov

After:

After.mov

@bc-dronov bc-dronov requested review from a team as code owners November 27, 2025 10:49
Comment on lines 113 to 122
}

deinitialize(): Promise<void> {
if (this._isDeinitializationBlocked) {
return Promise.resolve();
}

if (this._clickListener) {
this._paymentButton?.removeEventListener('click', this._clickListener);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Race condition can lead to orphaned event listener if deinitialize() is called during async operation.
Severity: MEDIUM | Confidence: Medium

🔍 Detailed Analysis

A race condition exists where deinitialize() can be called after _toggleBlockDeinitialization(true) is set within _interactWithPaymentSheet() but before _toggleBlockDeinitialization(false) is called. If this occurs, _isDeinitializationBlocked will be true, causing deinitialize() to return early without removing the event listener from the DOM. This leaves an orphaned event listener attached to the button element, potentially leading to memory leaks and unexpected behavior if the element remains in the DOM and is interacted with again.

💡 Suggested Fix

Modify deinitialize() to ensure the event listener is always removed, even if _isDeinitializationBlocked is true. This could involve waiting for the block to clear or forcefully removing the listener.

🤖 Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: packages/google-pay-integration/src/google-pay-payment-strategy.ts#L113-L122

Potential issue: A race condition exists where `deinitialize()` can be called after
`_toggleBlockDeinitialization(true)` is set within `_interactWithPaymentSheet()` but
before `_toggleBlockDeinitialization(false)` is called. If this occurs,
`_isDeinitializationBlocked` will be `true`, causing `deinitialize()` to return early
without removing the event listener from the DOM. This leaves an orphaned event listener
attached to the button element, potentially leading to memory leaks and unexpected
behavior if the element remains in the DOM and is interacted with again.

Did we get this right? 👍 / 👎 to inform future reviews.
Reference ID: 4019645

@bc-dronov bc-dronov force-pushed the fix/google_pay_tax_deinitialise branch from 4baa5e6 to 53676a7 Compare November 27, 2025 12:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants