From 1c20b57afc03a59fb385c138351d648ee6aaeb25 Mon Sep 17 00:00:00 2001 From: sam Date: Wed, 29 Jul 2026 18:34:07 -0700 Subject: [PATCH] Report email row errors from a side effect --- .../userprofile/email/UserProfileEmailRow.kt | 16 +++++++-- .../email/UserProfileEmailRowTest.kt | 33 +++++++++++++++++++ 2 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 source/ui/src/test/java/com/clerk/ui/userprofile/email/UserProfileEmailRowTest.kt diff --git a/source/ui/src/main/java/com/clerk/ui/userprofile/email/UserProfileEmailRow.kt b/source/ui/src/main/java/com/clerk/ui/userprofile/email/UserProfileEmailRow.kt index 89ec2debb..23921a6db 100644 --- a/source/ui/src/main/java/com/clerk/ui/userprofile/email/UserProfileEmailRow.kt +++ b/source/ui/src/main/java/com/clerk/ui/userprofile/email/UserProfileEmailRow.kt @@ -10,6 +10,7 @@ import androidx.compose.foundation.layout.padding import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -46,9 +47,8 @@ internal fun UserProfileEmailRow( val isPreview = LocalInspectionMode.current val state by viewModel.state.collectAsStateWithLifecycle() - if (state is EmailViewModel.State.Failure) { - onError((state as EmailViewModel.State.Failure).message) - } + ReportEmailRowError(state, onError) + ClerkMaterialTheme { Row( modifier = @@ -101,6 +101,16 @@ internal fun UserProfileEmailRow( } } +@Composable +internal fun ReportEmailRowError(state: EmailViewModel.State, onError: (String) -> Unit) { + val errorMessage = (state as? EmailViewModel.State.Failure)?.message + LaunchedEffect(errorMessage) { + if (errorMessage != null) { + onError(errorMessage) + } + } +} + @Composable private fun EmailWithBadge(isPrimary: Boolean, emailAddress: EmailAddress) { Column { diff --git a/source/ui/src/test/java/com/clerk/ui/userprofile/email/UserProfileEmailRowTest.kt b/source/ui/src/test/java/com/clerk/ui/userprofile/email/UserProfileEmailRowTest.kt new file mode 100644 index 000000000..17221735b --- /dev/null +++ b/source/ui/src/test/java/com/clerk/ui/userprofile/email/UserProfileEmailRowTest.kt @@ -0,0 +1,33 @@ +package com.clerk.ui.userprofile.email + +import androidx.compose.material3.Text +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.setValue +import com.clerk.base.BaseSnapshotTest +import kotlin.test.Test +import kotlin.test.assertEquals + +class UserProfileEmailRowTest : BaseSnapshotTest() { + + @Test + fun failureState_reportsErrorOnceAcrossRecomposition() { + val reportedErrors = mutableListOf() + val callbackVersions = mutableListOf() + var recompositionTrigger by mutableIntStateOf(0) + + paparazzi.snapshot { + val callbackVersion = recompositionTrigger + ReportEmailRowError(EmailViewModel.State.Failure("Unable to update email")) { + reportedErrors += it + callbackVersions += callbackVersion + } + Text(recompositionTrigger.toString()) + LaunchedEffect(Unit) { recompositionTrigger++ } + } + + assertEquals(listOf("Unable to update email"), reportedErrors) + assertEquals(listOf(0), callbackVersions) + } +}