Create specific errors for Invalid or Unsupporte homeserver.

This commit is contained in:
Benoit Marty 2025-11-07 09:41:57 +01:00
parent 3c3c81622f
commit a82c916ca9
7 changed files with 35 additions and 17 deletions

View file

@ -13,7 +13,6 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import dev.zacsweers.metro.Inject import dev.zacsweers.metro.Inject
import io.element.android.features.login.impl.R
import io.element.android.features.login.impl.accesscontrol.DefaultAccountProviderAccessControl import io.element.android.features.login.impl.accesscontrol.DefaultAccountProviderAccessControl
import io.element.android.features.login.impl.accountprovider.AccountProvider import io.element.android.features.login.impl.accountprovider.AccountProvider
import io.element.android.features.login.impl.accountprovider.AccountProviderDataSource import io.element.android.features.login.impl.accountprovider.AccountProviderDataSource
@ -63,10 +62,7 @@ class ChangeServerPresenter(
) )
val details = authenticationService.setHomeserver(data.url).getOrThrow() val details = authenticationService.setHomeserver(data.url).getOrThrow()
if (details.supportsOidcLogin.not() && details.supportsPasswordLogin.not()) { if (details.supportsOidcLogin.not() && details.supportsPasswordLogin.not()) {
// Unsupported homeserver throw ChangeServerError.UnsupportedServer
throw ChangeServerError.Error(
messageId = R.string.screen_login_error_unsupported_authentication,
)
} }
// Homeserver is valid, remember user choice // Homeserver is valid, remember user choice
accountProviderDataSource.userSelection(data) accountProviderDataSource.userSelection(data)

View file

@ -8,7 +8,6 @@
package io.element.android.features.login.impl.changeserver package io.element.android.features.login.impl.changeserver
import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.features.login.impl.R
import io.element.android.features.login.impl.error.ChangeServerError import io.element.android.features.login.impl.error.ChangeServerError
import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.libraries.ui.strings.CommonStrings
@ -37,9 +36,7 @@ open class ChangeServerStateProvider : PreviewParameterProvider<ChangeServerStat
), ),
aChangeServerState( aChangeServerState(
changeServerAction = AsyncData.Failure( changeServerAction = AsyncData.Failure(
ChangeServerError.Error( ChangeServerError.UnsupportedServer
R.string.screen_login_error_unsupported_authentication
)
) )
), ),
) )

View file

@ -39,6 +39,22 @@ fun ChangeServerView(
when (state.changeServerAction) { when (state.changeServerAction) {
is AsyncData.Failure -> { is AsyncData.Failure -> {
when (val error = state.changeServerAction.error as? ChangeServerError) { when (val error = state.changeServerAction.error as? ChangeServerError) {
ChangeServerError.InvalidServer ->
ErrorDialog(
modifier = modifier,
content = stringResource(R.string.screen_change_server_error_invalid_homeserver),
onSubmit = {
eventSink.invoke(ChangeServerEvents.ClearError)
}
)
ChangeServerError.UnsupportedServer ->
ErrorDialog(
modifier = modifier,
content = stringResource(R.string.screen_login_error_unsupported_authentication),
onSubmit = {
eventSink.invoke(ChangeServerEvents.ClearError)
}
)
is ChangeServerError.Error -> { is ChangeServerError.Error -> {
ErrorDialog( ErrorDialog(
modifier = modifier, modifier = modifier,

View file

@ -11,7 +11,6 @@ import androidx.annotation.StringRes
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import io.element.android.features.login.impl.R
import io.element.android.features.login.impl.changeserver.AccountProviderAccessException import io.element.android.features.login.impl.changeserver.AccountProviderAccessException
import io.element.android.libraries.matrix.api.auth.AuthenticationException import io.element.android.libraries.matrix.api.auth.AuthenticationException
import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.libraries.ui.strings.CommonStrings
@ -37,6 +36,8 @@ sealed class ChangeServerError : Exception() {
) : ChangeServerError() ) : ChangeServerError()
data object SlidingSyncAlert : ChangeServerError() data object SlidingSyncAlert : ChangeServerError()
data object InvalidServer : ChangeServerError()
data object UnsupportedServer : ChangeServerError()
companion object { companion object {
fun from(error: Throwable): ChangeServerError = when (error) { fun from(error: Throwable): ChangeServerError = when (error) {
@ -51,7 +52,7 @@ sealed class ChangeServerError : Exception() {
unauthorisedAccountProviderTitle = error.unauthorisedAccountProviderTitle, unauthorisedAccountProviderTitle = error.unauthorisedAccountProviderTitle,
authorisedAccountProviderTitles = error.authorisedAccountProviderTitles, authorisedAccountProviderTitles = error.authorisedAccountProviderTitles,
) )
else -> Error(messageId = R.string.screen_change_server_error_invalid_homeserver) else -> InvalidServer
} }
} }
} }

View file

@ -8,14 +8,11 @@
package io.element.android.features.login.impl.error package io.element.android.features.login.impl.error
import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.features.login.impl.R
class ChangeServerErrorProvider : PreviewParameterProvider<ChangeServerError> { class ChangeServerErrorProvider : PreviewParameterProvider<ChangeServerError> {
override val values: Sequence<ChangeServerError> override val values: Sequence<ChangeServerError>
get() = sequenceOf( get() = sequenceOf(
ChangeServerError.Error( ChangeServerError.InvalidServer,
messageId = R.string.screen_change_server_error_invalid_homeserver,
),
ChangeServerError.Error( ChangeServerError.Error(
messageStr = "An error description", messageStr = "An error description",
), ),
@ -28,5 +25,6 @@ class ChangeServerErrorProvider : PreviewParameterProvider<ChangeServerError> {
authorisedAccountProviderTitles = listOf("provider.org", "provider.io"), authorisedAccountProviderTitles = listOf("provider.org", "provider.io"),
), ),
ChangeServerError.SlidingSyncAlert, ChangeServerError.SlidingSyncAlert,
ChangeServerError.UnsupportedServer,
) )
} }

View file

@ -41,6 +41,17 @@ fun LoginModeView(
when (val error = loginMode.error) { when (val error = loginMode.error) {
is ChangeServerError -> { is ChangeServerError -> {
when (error) { when (error) {
ChangeServerError.InvalidServer ->
ErrorDialog(
content = stringResource(R.string.screen_change_server_error_invalid_homeserver),
onSubmit = onClearError,
)
is ChangeServerError.UnsupportedServer -> {
ErrorDialog(
content = stringResource(R.string.screen_login_error_unsupported_authentication),
onSubmit = onClearError,
)
}
is ChangeServerError.Error -> { is ChangeServerError.Error -> {
ErrorDialog( ErrorDialog(
content = error.message(), content = error.message(),

View file

@ -10,7 +10,6 @@ package io.element.android.features.login.impl.changeserver
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
import io.element.android.features.enterprise.api.EnterpriseService import io.element.android.features.enterprise.api.EnterpriseService
import io.element.android.features.enterprise.test.FakeEnterpriseService import io.element.android.features.enterprise.test.FakeEnterpriseService
import io.element.android.features.login.impl.R
import io.element.android.features.login.impl.aMatrixHomeServerDetails import io.element.android.features.login.impl.aMatrixHomeServerDetails
import io.element.android.features.login.impl.accesscontrol.DefaultAccountProviderAccessControl import io.element.android.features.login.impl.accesscontrol.DefaultAccountProviderAccessControl
import io.element.android.features.login.impl.accountprovider.AccountProvider import io.element.android.features.login.impl.accountprovider.AccountProvider
@ -117,7 +116,7 @@ class ChangeServerPresenterTest {
val failureState = awaitItem() val failureState = awaitItem()
assertThat(failureState.changeServerAction).isInstanceOf(AsyncData.Failure::class.java) assertThat(failureState.changeServerAction).isInstanceOf(AsyncData.Failure::class.java)
assertThat(failureState.changeServerAction.errorOrNull()).isEqualTo( assertThat(failureState.changeServerAction.errorOrNull()).isEqualTo(
ChangeServerError.Error(R.string.screen_login_error_unsupported_authentication) ChangeServerError.UnsupportedServer
) )
} }
} }