From 7f400b53d1f754eee38ae2c8082d6c0f923fd3a8 Mon Sep 17 00:00:00 2001 From: Nikos Douvlis Date: Fri, 2 May 2025 21:02:43 +0300 Subject: [PATCH 1/4] Revert "Revert "fix(clerk-js): Improve error handling for unexpected errors in checkout process (#5801)"" This reverts commit 10b72246f30b945ad2dc098c87b9dc34337f9c0f. --- .../src/ui/components/Checkout/CheckoutPage.tsx | 15 +++++++++++---- packages/clerk-js/src/ui/hooks/useCheckout.ts | 13 ++++++------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/packages/clerk-js/src/ui/components/Checkout/CheckoutPage.tsx b/packages/clerk-js/src/ui/components/Checkout/CheckoutPage.tsx index 3f888afc149..ef8427f99af 100644 --- a/packages/clerk-js/src/ui/components/Checkout/CheckoutPage.tsx +++ b/packages/clerk-js/src/ui/components/Checkout/CheckoutPage.tsx @@ -1,7 +1,11 @@ -import type { __experimental_CheckoutProps, __experimental_CommerceCheckoutResource } from '@clerk/types'; +import type { + __experimental_CheckoutProps, + __experimental_CommerceCheckoutResource, + ClerkAPIError, +} from '@clerk/types'; import { useEffect } from 'react'; -import { Alert, Box, localizationKeys, Spinner } from '../../customizables'; +import { Alert, Box, localizationKeys, Spinner, useLocalizations } from '../../customizables'; import { Drawer, useDrawerContext } from '../../elements'; import { useCheckout } from '../../hooks'; import { EmailForm } from '../UserProfile/EmailForm'; @@ -9,15 +13,18 @@ import { CheckoutComplete } from './CheckoutComplete'; import { CheckoutForm } from './CheckoutForm'; export const CheckoutPage = (props: __experimental_CheckoutProps) => { + const { translateError } = useLocalizations(); const { planId, planPeriod, subscriberType, onSubscriptionComplete } = props; const { setIsOpen, isOpen } = useDrawerContext(); - const { checkout, isLoading, invalidate, revalidate, updateCheckout, isMissingPayerEmail } = useCheckout({ + const { checkout, isLoading, invalidate, revalidate, updateCheckout, errors } = useCheckout({ planId, planPeriod, subscriberType, }); + const isMissingPayerEmail = errors.some((e: ClerkAPIError) => e.code === 'missing_payer_email'); + const onCheckoutComplete = (newCheckout: __experimental_CommerceCheckoutResource) => { invalidate(); // invalidate the initial checkout on complete updateCheckout(newCheckout); @@ -82,7 +89,7 @@ export const CheckoutPage = (props: __experimental_CheckoutProps) => { margin: 'auto', }} > - There was a problem, please try again later. + {errors[0] ? translateError(errors[0]) : 'There was a problem, please try again later.'} ); diff --git a/packages/clerk-js/src/ui/hooks/useCheckout.ts b/packages/clerk-js/src/ui/hooks/useCheckout.ts index 68e05ef6d2f..52bdc88c530 100644 --- a/packages/clerk-js/src/ui/hooks/useCheckout.ts +++ b/packages/clerk-js/src/ui/hooks/useCheckout.ts @@ -1,9 +1,6 @@ +import type { ClerkAPIResponseError } from '@clerk/shared'; import { useClerk, useOrganization, useUser } from '@clerk/shared/react'; -import type { - __experimental_CheckoutProps, - __experimental_CommerceCheckoutResource, - ClerkAPIError, -} from '@clerk/types'; +import type { __experimental_CheckoutProps, __experimental_CommerceCheckoutResource } from '@clerk/types'; import { useCallback, useEffect, useState } from 'react'; import { useFetch } from './useFetch'; @@ -20,7 +17,7 @@ export const useCheckout = (props: __experimental_CheckoutProps) => { isLoading, invalidate, revalidate, - error, + error: _error, } = useFetch( __experimental_commerce?.__experimental_billing.startCheckout, { @@ -32,6 +29,8 @@ export const useCheckout = (props: __experimental_CheckoutProps) => { `commerce-checkout-${user?.id}`, ); + const error = _error as ClerkAPIResponseError; + const updateCheckout = useCallback((newCheckout: __experimental_CommerceCheckoutResource) => { setCurrentCheckout(newCheckout); }, []); @@ -48,6 +47,6 @@ export const useCheckout = (props: __experimental_CheckoutProps) => { isLoading, invalidate, revalidate, - isMissingPayerEmail: error?.errors.some((e: ClerkAPIError) => e.code === 'missing_payer_email'), + errors: error.errors, }; }; From f6e9fa317b9e9bf0d4e3b4adc44f48e63ca63f04 Mon Sep 17 00:00:00 2001 From: Nikos Douvlis Date: Fri, 2 May 2025 21:10:00 +0300 Subject: [PATCH 2/4] fix(clerk-js): Handle potential undefined errors in checkout process --- .../ui/components/Checkout/CheckoutPage.tsx | 28 +++++++++++-------- packages/clerk-js/src/ui/hooks/useCheckout.ts | 4 +-- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/packages/clerk-js/src/ui/components/Checkout/CheckoutPage.tsx b/packages/clerk-js/src/ui/components/Checkout/CheckoutPage.tsx index ef8427f99af..428b6faff75 100644 --- a/packages/clerk-js/src/ui/components/Checkout/CheckoutPage.tsx +++ b/packages/clerk-js/src/ui/components/Checkout/CheckoutPage.tsx @@ -5,7 +5,7 @@ import type { } from '@clerk/types'; import { useEffect } from 'react'; -import { Alert, Box, localizationKeys, Spinner, useLocalizations } from '../../customizables'; +import { Alert, Box, Flex, localizationKeys, Spinner, useLocalizations } from '../../customizables'; import { Drawer, useDrawerContext } from '../../elements'; import { useCheckout } from '../../hooks'; import { EmailForm } from '../UserProfile/EmailForm'; @@ -23,7 +23,7 @@ export const CheckoutPage = (props: __experimental_CheckoutProps) => { subscriberType, }); - const isMissingPayerEmail = errors.some((e: ClerkAPIError) => e.code === 'missing_payer_email'); + const isMissingPayerEmail = !!errors?.some((e: ClerkAPIError) => e.code === 'missing_payer_email'); const onCheckoutComplete = (newCheckout: __experimental_CommerceCheckoutResource) => { invalidate(); // invalidate the initial checkout on complete @@ -81,16 +81,20 @@ export const CheckoutPage = (props: __experimental_CheckoutProps) => { } return ( - <> - {/* TODO(@COMMERCE): needs localization */} - + ({ + height: '100%', + padding: t.space.$4, + fontSize: t.fontSizes.$md, + })} > - {errors[0] ? translateError(errors[0]) : 'There was a problem, please try again later.'} - - + + {errors ? translateError(errors[0]) : 'There was a problem, please try again later.'} + + + ); }; diff --git a/packages/clerk-js/src/ui/hooks/useCheckout.ts b/packages/clerk-js/src/ui/hooks/useCheckout.ts index 52bdc88c530..aac6c431bcc 100644 --- a/packages/clerk-js/src/ui/hooks/useCheckout.ts +++ b/packages/clerk-js/src/ui/hooks/useCheckout.ts @@ -29,7 +29,7 @@ export const useCheckout = (props: __experimental_CheckoutProps) => { `commerce-checkout-${user?.id}`, ); - const error = _error as ClerkAPIResponseError; + const error = _error as ClerkAPIResponseError | undefined; const updateCheckout = useCallback((newCheckout: __experimental_CommerceCheckoutResource) => { setCurrentCheckout(newCheckout); @@ -47,6 +47,6 @@ export const useCheckout = (props: __experimental_CheckoutProps) => { isLoading, invalidate, revalidate, - errors: error.errors, + errors: error?.errors, }; }; From 97de88b6d0913879eef7426bc0d210f0b7dd1edd Mon Sep 17 00:00:00 2001 From: Nikos Douvlis Date: Fri, 2 May 2025 21:20:52 +0300 Subject: [PATCH 3/4] Create mighty-worms-watch.md --- .changeset/mighty-worms-watch.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/mighty-worms-watch.md diff --git a/.changeset/mighty-worms-watch.md b/.changeset/mighty-worms-watch.md new file mode 100644 index 00000000000..b5118a50901 --- /dev/null +++ b/.changeset/mighty-worms-watch.md @@ -0,0 +1,5 @@ +--- +"@clerk/clerk-js": patch +--- + +Show a localized message for all errors returned from the backend if the user tries to perform an invalid plan change. From dc5d1a412032ce91b57a1ff406fe6f016ad8229a Mon Sep 17 00:00:00 2001 From: Nikos Douvlis Date: Fri, 2 May 2025 21:29:14 +0300 Subject: [PATCH 4/4] fix(clerk-js): Update bundlewatch.config.json --- packages/clerk-js/bundlewatch.config.json | 2 +- packages/clerk-js/src/ui/hooks/useCheckout.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/clerk-js/bundlewatch.config.json b/packages/clerk-js/bundlewatch.config.json index 72395d72abe..47b4a4fdd85 100644 --- a/packages/clerk-js/bundlewatch.config.json +++ b/packages/clerk-js/bundlewatch.config.json @@ -21,7 +21,7 @@ { "path": "./dist/waitlist*.js", "maxSize": "1.3KB" }, { "path": "./dist/keylessPrompt*.js", "maxSize": "6.5KB" }, { "path": "./dist/pricingTable*.js", "maxSize": "4.02KB" }, - { "path": "./dist/checkout*.js", "maxSize": "5.2KB" }, + { "path": "./dist/checkout*.js", "maxSize": "5.3KB" }, { "path": "./dist/paymentSources*.js", "maxSize": "8.9KB" }, { "path": "./dist/up-billing-page*.js", "maxSize": "2.4KB" }, { "path": "./dist/op-billing-page*.js", "maxSize": "2.4KB" }, diff --git a/packages/clerk-js/src/ui/hooks/useCheckout.ts b/packages/clerk-js/src/ui/hooks/useCheckout.ts index aac6c431bcc..5dac8c76cb9 100644 --- a/packages/clerk-js/src/ui/hooks/useCheckout.ts +++ b/packages/clerk-js/src/ui/hooks/useCheckout.ts @@ -1,4 +1,4 @@ -import type { ClerkAPIResponseError } from '@clerk/shared'; +import type { ClerkAPIResponseError } from '@clerk/shared/error'; import { useClerk, useOrganization, useUser } from '@clerk/shared/react'; import type { __experimental_CheckoutProps, __experimental_CommerceCheckoutResource } from '@clerk/types'; import { useCallback, useEffect, useState } from 'react';