diff --git a/apps/web/src/components/Basenames/RegistrationProfileForm/index.tsx b/apps/web/src/components/Basenames/RegistrationProfileForm/index.tsx index 3856b5bfe1c..fb1ddd368e4 100644 --- a/apps/web/src/components/Basenames/RegistrationProfileForm/index.tsx +++ b/apps/web/src/components/Basenames/RegistrationProfileForm/index.tsx @@ -73,11 +73,14 @@ export default function RegistrationProfileForm() { } if (currentFormStep === FormSteps.Keywords) { - writeTextRecords() - .then() - .catch((error) => { + // Handle async operation with void to acknowledge we're intentionally not awaiting + void (async () => { + try { + await writeTextRecords(); + } catch (error) { logError(error, 'Failed to write text records'); - }); + } + })(); } event.preventDefault(); diff --git a/apps/web/src/components/Basenames/RegistrationSuccessMessage/index.tsx b/apps/web/src/components/Basenames/RegistrationSuccessMessage/index.tsx index e9328d11009..88f1040b358 100644 --- a/apps/web/src/components/Basenames/RegistrationSuccessMessage/index.tsx +++ b/apps/web/src/components/Basenames/RegistrationSuccessMessage/index.tsx @@ -23,21 +23,26 @@ export default function RegistrationSuccessMessage() { const claimUSDC = useCallback(() => { setPopupMessage('USDC is being sent to your wallet'); - fetch(`${process.env.NEXT_PUBLIC_USDC_URL}?address=${address}`, { - method: 'GET', - headers: { 'Content-Type': 'application/json' }, - }) - .then(async (response) => { + // Handle async operation with void to acknowledge we're intentionally not awaiting + void (async () => { + try { + const response = await fetch(`${process.env.NEXT_PUBLIC_USDC_URL}?address=${address}`, { + method: 'GET', + headers: { 'Content-Type': 'application/json' }, + }); + if (!response.ok) { const resp = (await response.json()) as { error: string }; throw new Error(resp.error); } setPopupMessage('USDC claimed successfully!'); - }) - .catch((error) => { - setPopupMessage(`${error.message}`); + } catch (error) { + const errorMessage = + error instanceof Error ? error.message : 'Failed to claim USDC: Unknown error'; + setPopupMessage(errorMessage); console.error('Error:', error); - }); + } + })(); }, [address]); const closePopup = useCallback(() => setPopupMessage(null), []); diff --git a/apps/web/src/components/Basenames/UsernameProfileSettingsAvatar/index.tsx b/apps/web/src/components/Basenames/UsernameProfileSettingsAvatar/index.tsx index 5caa3e98c0b..dd9d5639baf 100644 --- a/apps/web/src/components/Basenames/UsernameProfileSettingsAvatar/index.tsx +++ b/apps/web/src/components/Basenames/UsernameProfileSettingsAvatar/index.tsx @@ -69,13 +69,12 @@ export default function UsernameProfileSettingsAvatar() { [logError, profileUsername, updateTextRecords], ); - const saveAvatar = useCallback(() => { - // Write the records - writeTextRecords() - .then() - .catch((error) => { - logError(error, 'Failed to write text records'); - }); + const saveAvatar = useCallback(async () => { + try { + await writeTextRecords(); + } catch (error) { + logError(error, 'Failed to write text records'); + } }, [logError, writeTextRecords]); const onClickSave = useCallback( @@ -85,20 +84,22 @@ export default function UsernameProfileSettingsAvatar() { if (!currentWalletIsProfileEditor) return false; if (avatarFile) { - uploadFile(avatarFile) - .then((result) => { + // Handle async operation with void to acknowledge we're intentionally not awaiting + void (async () => { + try { + const result = await uploadFile(avatarFile); // set the uploaded result as the url if (result) { logEventWithContext('avatar_upload_success', ActionType.change); setAvatarUploadedAndReadyToSave(true); } - }) - .catch((error) => { + } catch (error) { logError(error, 'Failed to upload avatar'); logEventWithContext('avatar_upload_failed', ActionType.error); - }); + } + })(); } else { - saveAvatar(); + void saveAvatar(); } }, [ @@ -113,7 +114,7 @@ export default function UsernameProfileSettingsAvatar() { useEffect(() => { if (avatarUploadAndReadyToSave) { - saveAvatar(); + void saveAvatar(); setAvatarUploadedAndReadyToSave(false); } }, [avatarUploadAndReadyToSave, saveAvatar]); diff --git a/apps/web/src/components/Basenames/UsernameProfileSidebar/index.tsx b/apps/web/src/components/Basenames/UsernameProfileSidebar/index.tsx index c54e7a6e145..f0632cc39f7 100644 --- a/apps/web/src/components/Basenames/UsernameProfileSidebar/index.tsx +++ b/apps/web/src/components/Basenames/UsernameProfileSidebar/index.tsx @@ -77,21 +77,31 @@ export default function UsernameProfileSidebar() { const reclaimProfile = useCallback(() => { if (!reclaimContract) return; - initiateReclaim(reclaimContract) - .then((result) => console.log({ result })) - .catch((error) => { + + // Handle async operation with void to acknowledge we're intentionally not awaiting + void (async () => { + try { + const result = await initiateReclaim(reclaimContract); + console.log({ result }); + } catch (error) { logError(error, 'Failed to reclaim profile'); - }); + } + })(); }, [initiateReclaim, logError, reclaimContract]); useEffect(() => { - if (reclaimStatus === WriteTransactionWithReceiptStatus.Success) { - profileRefetch() - .then() - .catch((error) => { - logError(error, 'Failed to refetch profile'); - }); + // Refetch profile after successful reclaim + async function handleRefetch() { + if (reclaimStatus !== WriteTransactionWithReceiptStatus.Success) return; + + try { + await profileRefetch(); + } catch (error) { + logError(error, 'Failed to refetch profile'); + } } + + void handleRefetch(); }, [logError, profileRefetch, reclaimStatus]); const textRecordKeywords = existingTextRecords[UsernameTextRecordKeys.Keywords]; diff --git a/apps/web/src/components/Basenames/UsernameProfileTransferOwnershipModal/index.tsx b/apps/web/src/components/Basenames/UsernameProfileTransferOwnershipModal/index.tsx index d03eb2b5396..1f79b064347 100644 --- a/apps/web/src/components/Basenames/UsernameProfileTransferOwnershipModal/index.tsx +++ b/apps/web/src/components/Basenames/UsernameProfileTransferOwnershipModal/index.tsx @@ -86,14 +86,16 @@ export default function UsernameProfileTransferOwnershipModal({ return; } - profileRefetch() - .then(() => { + // Handle async operation with void to acknowledge we're intentionally not awaiting + void (async () => { + try { + await profileRefetch(); setShowProfileSettings(false); onClose(); - }) - .catch((error) => { + } catch (error) { logError(error, 'Failed to refetch Owner'); - }); + } + })(); }, [currentOwnershipStep, logError, onClose, profileRefetch, setShowProfileSettings]); // Memos diff --git a/apps/web/src/components/ConnectWalletButton/CustomWalletAdvancedAddressDetails.tsx b/apps/web/src/components/ConnectWalletButton/CustomWalletAdvancedAddressDetails.tsx index a58bd765b26..3d72b18ab48 100644 --- a/apps/web/src/components/ConnectWalletButton/CustomWalletAdvancedAddressDetails.tsx +++ b/apps/web/src/components/ConnectWalletButton/CustomWalletAdvancedAddressDetails.tsx @@ -11,17 +11,18 @@ export function CustomWalletAdvancedAddressDetails() { const [, copy] = useCopyToClipboard(); const handleCopyAddress = useCallback(() => { - copy(String(address)) - .then(() => { + // Handle async operation with void to acknowledge we're intentionally not awaiting + void (async () => { + try { + await copy(String(address)); setCopyText('Copied'); - }) - .catch((err) => { + } catch (err) { setCopyText('Failed to copy'); console.error('Failed to copy address:', err); - }) - .finally(() => { + } finally { setTimeout(() => setCopyText('Copy'), 2000); - }); + } + })(); }, [address, copy]); if (!address || !chain) { diff --git a/apps/web/src/components/ImageCloudinary/index.tsx b/apps/web/src/components/ImageCloudinary/index.tsx index 8b0b20e2687..4cba47523fe 100644 --- a/apps/web/src/components/ImageCloudinary/index.tsx +++ b/apps/web/src/components/ImageCloudinary/index.tsx @@ -51,6 +51,7 @@ export default function ImageCloudinary({ // ref: https://support.cloudinary.com/hc/en-us/articles/209209649-Does-Cloudinary-impose-a-URL-length-limit if (shouldUploadToCloudinary) { + // Fetch Cloudinary URL and handle errors with async/await async function handleGetCloudinaryUrl() { try { const response = await fetch('/api/cloudinaryUrl', { @@ -78,9 +79,7 @@ export default function ImageCloudinary({ } } - handleGetCloudinaryUrl() - .then() - .catch((error) => console.log(error)); + void handleGetCloudinaryUrl(); } }, [absoluteSrc, shouldUploadToCloudinary, width]); diff --git a/apps/web/src/components/NeynarCast/index.tsx b/apps/web/src/components/NeynarCast/index.tsx index 75ed5dbc46b..ad0ec15cdcd 100644 --- a/apps/web/src/components/NeynarCast/index.tsx +++ b/apps/web/src/components/NeynarCast/index.tsx @@ -112,13 +112,17 @@ export default function NeynarCast({ const [data, setData] = useState(); const { logError } = useErrors(); useEffect(() => { - fetchCast({ type, identifier }) - .then((result) => { + // Fetch Neynar cast data with async/await + async function loadCast() { + try { + const result = await fetchCast({ type, identifier }); if (result) setData(result); - }) - .catch((error) => { + } catch (error) { logError(error, 'Failed to load Cast'); - }); + } + } + + void loadCast(); }, [identifier, logError, type]); const onClickCast = useCallback( diff --git a/apps/web/src/components/ThreeHero/DynamicRigidBody.tsx b/apps/web/src/components/ThreeHero/DynamicRigidBody.tsx index f912d80499b..b63692bb209 100644 --- a/apps/web/src/components/ThreeHero/DynamicRigidBody.tsx +++ b/apps/web/src/components/ThreeHero/DynamicRigidBody.tsx @@ -10,13 +10,18 @@ export const DynamicRigidBody = forwardRef( const [RigidBodyDynamic, setRigidBody] = useState(); const { logError } = useErrors(); - // Import needs to happen on render + // Import needs to happen on render with async/await useEffect(() => { - import('@react-three/rapier') - .then((mod) => { + async function loadRigidBody() { + try { + const mod = await import('@react-three/rapier'); setRigidBody(() => mod.RigidBody); - }) - .catch((error) => logError(error, 'Failed to load RigidBody')); + } catch (error) { + logError(error, 'Failed to load RigidBody'); + } + } + + void loadRigidBody(); }, [logError]); if (!RigidBodyDynamic) return null; diff --git a/apps/web/src/hooks/useSetPrimaryBasename.ts b/apps/web/src/hooks/useSetPrimaryBasename.ts index aafec1d432d..f6fcd36c365 100644 --- a/apps/web/src/hooks/useSetPrimaryBasename.ts +++ b/apps/web/src/hooks/useSetPrimaryBasename.ts @@ -95,11 +95,18 @@ export default function useSetPrimaryBasename({ secondaryUsername }: UseSetPrima }, [address, secondaryUsername, secondaryUsernameChain.id, signMessageAsync]); useEffect(() => { - if (transactionIsSuccess) { - refetchPrimaryUsername() - .then() - .catch((error) => logError(error, 'failed to refetch username')); + // Refetch the primary username after a successful transaction + async function handleRefetch() { + if (!transactionIsSuccess) return; + + try { + await refetchPrimaryUsername(); + } catch (error) { + logError(error, 'failed to refetch username'); + } } + + void handleRefetch(); }, [logError, refetchPrimaryUsername, transactionIsSuccess]); const setPrimaryName = useCallback(async (): Promise => { diff --git a/apps/web/src/utils/logger.ts b/apps/web/src/utils/logger.ts index 786ebe767a2..ea29a8aa97b 100644 --- a/apps/web/src/utils/logger.ts +++ b/apps/web/src/utils/logger.ts @@ -62,9 +62,14 @@ class CustomLogger { console.error(logEntry); // Skip Bugsnag during E2E tests if (process.env.E2E_TEST !== 'true') { - bugsnagNotify(message, (e) => e.addMetadata('baseweb', { meta })).catch((e) => - console.error('Error reporting to Bugsnag', e), - ); + // Report error to Bugsnag with async/await - fire and forget + void (async () => { + try { + await bugsnagNotify(message, (e) => e.addMetadata('baseweb', { meta })); + } catch (e) { + console.error('Error reporting to Bugsnag', e); + } + })(); } break; default: diff --git a/libs/base-ui/contexts/Experiments.tsx b/libs/base-ui/contexts/Experiments.tsx index 313a813da8e..bcef6fd289a 100644 --- a/libs/base-ui/contexts/Experiments.tsx +++ b/libs/base-ui/contexts/Experiments.tsx @@ -61,13 +61,17 @@ export default function ExperimentsProvider({ children }: ExperimentsProviderPro }, [experimentClient]); useEffect(() => { - startExperiment() - .then(() => { + // Start the experiment client and handle errors with async/await + async function initializeExperiment() { + try { + await startExperiment(); setIsReady(true); - }) - .catch((error) => { + } catch (error) { console.log(`Error starting experiments for ${ampDeploymentKey}:`, error); - }); + } + } + + void initializeExperiment(); }, [experimentClient, startExperiment]); const getUserVariant = useCallback(