Skip to content

fix(checkout): CHECKOUT-10193 Add retry to checkout-button-resolver - #3270

Open
bc-maxy wants to merge 6 commits into
masterfrom
checkout-10193
Open

fix(checkout): CHECKOUT-10193 Add retry to checkout-button-resolver#3270
bc-maxy wants to merge 6 commits into
masterfrom
checkout-10193

Conversation

@bc-maxy

@bc-maxy bc-maxy commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

What/Why?

Shoppers on flaky networks who fail to fetch the wallet-button-v1-resolver chunk now get up to 5 automatic retries, and if all fail, top-of-checkout wallet buttons degrade to errorFallback={null}.

The reason it is set to null and not to default error network message is because this evaluation is per wallet button - so then we can end up with multiple messages. With the null instead the shopper will see checkout without some of wallet buttons that failed to resolve instead of throwing an unhandled ChunkLoadError and breaking the whole checkout flow). No visual change on the happy path.

Worst case adds ~4s of retry delay before showing the error state, which is the intended trade-off.

Rollout/Rollback

Revert the PR.

Testing

New CI tests.


Note

Medium Risk
Touches checkout wallet-button loading and loading-skeleton behavior; failures degrade to missing buttons rather than a hard error, but shoppers may lose wallet options on persistent chunk failures.

Overview
Wallet button lazy loads now use the shared retry helper when importing wallet-button-v1-resolver (and the same pattern in the button list), so transient chunk fetch failures are retried before surfacing a ChunkLoadError.

Error handling for lazy wallet UI is extended so ErrorBoundary can invoke an optional onError, and LazyContainer accepts configurable errorFallback and onError while still only catching ChunkLoadError. Checkout wallet areas pass errorFallback={null} so a failed button disappears instead of showing multiple “unstable network” messages or breaking the whole checkout.

Top-of-checkout loading state moves into CheckoutButtonContainer: it tracks per-method chunk failures, recomputes isLoading from customer init status (excluding failed methods), and swaps Suspense for LazyContainer with per-button error callbacks so the wallet skeleton clears when all buttons fail or stay visible while other buttons still initialize.

Reviewed by Cursor Bugbot for commit 9ecac59. Bugbot is set up for automated code reviews on this repo. Configure here.

@bc-maxy bc-maxy changed the title Checkout 10193 fix(checkout): CHECKOUT-10193 Add retry to checkout-button-resolver Aug 21, 2026
@bc-maxy

bc-maxy commented Aug 21, 2026

Copy link
Copy Markdown
Contributor Author

cursor review

Comment thread packages/core/src/app/customer/CheckoutButtonContainer.tsx
@bc-maxy

bc-maxy commented Aug 21, 2026

Copy link
Copy Markdown
Contributor Author

cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit e59fcf2. Configure here.

@bc-maxy

bc-maxy commented Aug 21, 2026

Copy link
Copy Markdown
Contributor Author

cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit e9e1547. Configure here.

@bc-maxy
bc-maxy marked this pull request as ready for review August 24, 2026 06:35
@bc-maxy
bc-maxy requested a review from a team as a code owner August 24, 2026 06:35
Comment on lines +32 to +34
if (onError) {
onError(error);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Do we have other options to retry the resolver besides touching ErrorBoundary?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The error boundary part is I guess a separate issue from retries. What bugbot mentioned above is that without onError callback isLoading never clears and the skeleton keeps all buttons hidden from the screen (cause we apply top: -300%).

Do you think I should move this change to another PR and just keep retries in this one?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I didn't read Cursor review😂 Just tried to understand the reasoning of changing ErrorBoundary because ErrorBoundary is bit legacy.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Ah I see 😄 Well that's the only error boundary I saw used in the repo, do we have an alternative? I thought React requires it to be a class, but maybe that's changed now 😄

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I see we need to update ErrorBoundary to handle a loading error with:

   const handleChunkLoadError = () => {
        setHasChunkLoadError(true);
    };

Is it possible that we do isLoading={isLoading && !hasChunkLoadError} in the other way, such as only hiding it when all wallet buttons are properly loaded?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good point! What do you think about this change: 9ecac59 ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

methodId could be a dangerous prop. Let’s discuss this offline.

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.

2 participants