From e991e3f64feed9a0f4910f900a84073a211d26b2 Mon Sep 17 00:00:00 2001 From: Tomek Zawadzki Date: Tue, 25 Aug 2026 17:35:15 +0200 Subject: [PATCH] Keep the DeleteAccountDialog guard inside the try Addresses review feedback on #11545. Hoisting the guard above the try moved the throw past the catch, so a falsy did became an unhandled rejection with no inline error, no log and no step reset. Reverting outright would re-break compilation - confirmDeletion is a nested callback of the component, so its throw is part of the same compiled unit. The check stays where it was; only the throw and the optional chain move to a module-scope requireAccount. Co-Authored-By: Claude Opus 5 (1M context) --- .../components/DeleteAccountDialog.tsx | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/screens/Settings/components/DeleteAccountDialog.tsx b/src/screens/Settings/components/DeleteAccountDialog.tsx index 68f302b4ba..195861a43a 100644 --- a/src/screens/Settings/components/DeleteAccountDialog.tsx +++ b/src/screens/Settings/components/DeleteAccountDialog.tsx @@ -8,6 +8,7 @@ import {useCleanError} from '#/lib/hooks/useCleanError' import {sanitizeHandle} from '#/lib/strings/handles' import {logger} from '#/logger' import { + type SessionAccount, useChatClient, usePdsClient, useSession, @@ -49,6 +50,17 @@ function isPasswordValid(password: string) { return password.length >= PASSWORD_MIN_LENGTH } +/** + * Out of the component because React Compiler cannot lower a `throw`, or the + * optional chain in this check, inside a `try`. Keeping the check in the `try` - + * rather than hoisting it above - means the catch below still runs: inline + * error, log, and reset to the code step. + */ +function requireAccount(account: SessionAccount | undefined): SessionAccount { + if (!account?.did) throw new Error('Invalid did') + return account +} + export function DeleteAccountDialog({ control, deactivateDialogControl, @@ -111,11 +123,9 @@ function DeleteAccountDialogInner({ }, [client, cleanError, emailState, setEmailState]) const confirmDeletion = useCallback(async () => { - if (!currentAccount?.did) { - throw new Error('Invalid did') - } try { setError('') + const account = requireAccount(currentAccount) const token = confirmCode.replace(WHITESPACE_RE, '') /* * Inform chat service of intent to delete account. A non-2xx response @@ -124,14 +134,14 @@ function DeleteAccountDialogInner({ */ await chatClient.call(chat.bsky.actor.deleteAccount) await client.call(com.atproto.server.deleteAccount, { - did: currentAccount.did, + did: account.did, password, token, }) control.close(() => { toast.show(_(msg`Your account has been deleted, see ya! ✌️`)) resetToTab('HomeTab') - removeAccount(currentAccount) + removeAccount(account) }) } catch (e: any) { const {clean, raw} = cleanError(e)