Skip to content

Commit

Permalink
catch unmount errors (#446)
Browse files Browse the repository at this point in the history
  • Loading branch information
cweiss-stripe committed Sep 26, 2023
1 parent 1441b7a commit f44a072
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 2 deletions.
25 changes: 25 additions & 0 deletions src/components/EmbeddedCheckout.client.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,4 +129,29 @@ describe('EmbeddedCheckout on the client', () => {
);
expect(mockEmbeddedCheckout.unmount).toBeCalled();
});

it('does not throw when the Embedded Checkout instance is already destroyed when unmounting', async () => {
const {container, rerender} = render(
<EmbeddedCheckoutProvider stripe={mockStripe} options={fakeOptions}>
<EmbeddedCheckout />
</EmbeddedCheckoutProvider>
);

await act(() => mockEmbeddedCheckoutPromise);

expect(mockEmbeddedCheckout.mount).toBeCalledWith(container.firstChild);

mockEmbeddedCheckout.unmount.mockImplementation(() => {
throw new Error('instance has been destroyed');
});

expect(() => {
rerender(
<EmbeddedCheckoutProvider
stripe={mockStripe}
options={fakeOptions}
></EmbeddedCheckoutProvider>
);
}).not.toThrow();
});
});
13 changes: 11 additions & 2 deletions src/components/EmbeddedCheckout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,17 @@ const EmbeddedCheckoutClientElement = ({
// Clean up on unmount
return () => {
if (isMounted.current && embeddedCheckout) {
embeddedCheckout.unmount();
isMounted.current = false;
try {
embeddedCheckout.unmount();
isMounted.current = false;
} catch (e) {
// Do nothing.
// Parent effects are destroyed before child effects, so
// in cases where both the EmbeddedCheckoutProvider and
// the EmbeddedCheckout component are removed at the same
// time, the embeddedCheckout instance will be destroyed,
// which causes an error when calling unmount.
}
}
};
}, [embeddedCheckout]);
Expand Down

0 comments on commit f44a072

Please sign in to comment.