Unblock React Compiler for 5 components with early exits inside try (#11547)

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Tomasz Zawadzki
2026-08-31 15:52:17 +02:00
committed by GitHub
parent f9cf58ea44
commit a086a2ebe0
5 changed files with 45 additions and 18 deletions
+6 -6
View File
@@ -21,12 +21,12 @@ export function useGoogleTranslate() {
if (IS_ANDROID) {
try {
// use `getApplicationIconAsync` to determine if the translate app is installed
if (
!(await IntentLauncher.getApplicationIconAsync(
'com.google.android.apps.translate',
))
) {
throw new Error('Translate app not installed')
const installed = await IntentLauncher.getApplicationIconAsync(
'com.google.android.apps.translate',
)
if (!installed) {
openLink(translateUrl)
return
}
// TODO: this should only be called one at a time, use something like
@@ -83,10 +83,10 @@ export function BetaFeaturesSettingsScreen({}: Props) {
} catch (e) {
logger.error('Failed to toggle beta features', {safeMessage: e})
Toast.show(l`Something went wrong, please try again.`, {type: 'error'})
return
} finally {
setIsPending(false)
return
}
setIsPending(false)
/*
* The toggle already succeeded; re-evaluate feature gates against the new
* attribute in-session as a best-effort follow-up. A failure here should
+4 -3
View File
@@ -76,10 +76,11 @@ export function StepHandle() {
dispatch({type: 'setIsLoading', value: true})
const serviceDid = state.serviceDescription?.did ?? 'UNKNOWN'
try {
const {available: handleAvailable} = await checkHandleAvailability(
createFullHandle(handle, state.userDomain),
state.serviceDescription?.did ?? 'UNKNOWN',
serviceDid,
{},
)
@@ -90,6 +91,7 @@ export function StepHandle() {
value: _(msg`That username is already taken`),
field: 'handle',
})
dispatch({type: 'setIsLoading', value: false})
return
} else {
ax.metric('signup:handleAvailable', {typeahead: false})
@@ -99,9 +101,8 @@ export function StepHandle() {
safeMessage: error,
})
// do nothing on error, let them pass
} finally {
dispatch({type: 'setIsLoading', value: false})
}
dispatch({type: 'setIsLoading', value: false})
ax.metric('signup:nextPressed', {
activeStep: state.activeStep,
+4 -3
View File
@@ -322,6 +322,7 @@ export function useSubmitSignup() {
dispatch({type: 'setError', value: ''})
dispatch({type: 'setIsLoading', value: true})
const verificationCode = state.pendingSubmit?.verificationCode
try {
await createAccount(
{
@@ -331,7 +332,7 @@ export function useSubmitSignup() {
password: state.password,
birthDate: state.dateOfBirth,
inviteCode: state.inviteCode.trim(),
verificationCode: state.pendingSubmit?.verificationCode,
verificationCode,
},
{
signupDuration: Date.now() - state.signupStartTime,
@@ -360,6 +361,7 @@ export function useSubmitSignup() {
field: 'invite-code',
})
dispatch({type: 'setStep', value: SignupStep.INFO})
dispatch({type: 'setIsLoading', value: false})
return
}
@@ -384,9 +386,8 @@ export function useSubmitSignup() {
safeMessage: e,
})
}
} finally {
dispatch({type: 'setIsLoading', value: false})
}
dispatch({type: 'setIsLoading', value: false})
},
[l, ax, createAccount, onboardingDispatch],
)
+29 -4
View File
@@ -10,6 +10,25 @@ import {updatePostShadow} from '../cache/post-shadow'
import {useAppviewClient, useSession} from '../session'
import {useProfileUpdateMutation} from './profile'
/**
* Out of the hook because React Compiler cannot lower a `throw` inside a `try`.
* Keeping the check in place - rather than hoisting it above the `try` - means
* the catch below still shows its toast and reverts the optimistic update.
*/
function assertSignedIn(account: unknown): asserts account {
if (!account) throw new Error('Not signed in')
}
/**
* Out of the hook because React Compiler cannot lower an optional chain inside a
* `try` block, and `profile` only exists once the request inside it resolves.
*/
function getPinnedPostUri(profile: {
pinnedPost?: {uri: string}
}): string | undefined {
return profile.pinnedPost?.uri
}
export function usePinnedPostMutation() {
const {_} = useLingui()
const {currentAccount} = useSession()
@@ -33,13 +52,19 @@ export function usePinnedPostMutation() {
updatePostShadow(queryClient, postUri, {pinned: pinCurrentPost})
// get the currently pinned post so we can optimistically remove the pin from it
if (!currentAccount) throw new Error('Not signed in')
assertSignedIn(currentAccount)
const profile = await client.call(app.bsky.actor.getProfile, {
actor: currentAccount.did,
})
prevPinnedPost = profile.pinnedPost?.uri
if (prevPinnedPost && prevPinnedPost !== postUri) {
updatePostShadow(queryClient, prevPinnedPost, {pinned: false})
prevPinnedPost = getPinnedPostUri(profile)
if (prevPinnedPost) {
/*
* Nested rather than `&&`: React Compiler cannot lower a logical
* expression in a test position inside a `try`.
*/
if (prevPinnedPost !== postUri) {
updatePostShadow(queryClient, prevPinnedPost, {pinned: false})
}
}
await profileUpdateMutate({