From 365c03e76365a2669ed9698cd67ce3e144eea98f Mon Sep 17 00:00:00 2001 From: SpiritCroc Date: Tue, 29 Mar 2022 12:45:23 +0200 Subject: [PATCH 1/2] Load timeline without initial eventId if not found --- changelog.d/5659.bugfix | 1 + .../session/room/timeline/DefaultTimeline.kt | 18 +++++++++++++++++- .../room/timeline/LoadTimelineStrategy.kt | 6 ++++++ 3 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 changelog.d/5659.bugfix diff --git a/changelog.d/5659.bugfix b/changelog.d/5659.bugfix new file mode 100644 index 0000000000..eec39a7738 --- /dev/null +++ b/changelog.d/5659.bugfix @@ -0,0 +1 @@ +Fix endless loading if the event from a permalink is not found diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt index 8c2b4d2bbe..99b9683c31 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt @@ -223,7 +223,15 @@ internal class DefaultTimeline(private val roomId: String, updateState(direction) { it.copy(loading = true) } - val loadMoreResult = strategy.loadMore(count, direction, fetchOnServerIfNeeded) + val loadMoreResult = try { + strategy.loadMore(count, direction, fetchOnServerIfNeeded) + } catch (throwable: Throwable) { + // Timeline could not be loaded with a (likely) permanent issue, such as the + // server now knowing the initialEventId, so we want to show an error message + // and possibly restart without initialEventId. + onTimelineFailure(throwable) + return false + } Timber.v("$baseLogMessage: result $loadMoreResult") val hasMoreToLoad = loadMoreResult != LoadMoreResult.REACHED_END updateState(direction) { @@ -342,6 +350,14 @@ internal class DefaultTimeline(private val roomId: String, } } + private fun onTimelineFailure(throwable: Throwable) { + timelineScope.launch(coroutineDispatchers.main) { + listeners.forEach { + tryOrNull { it.onTimelineFailure(throwable) } + } + } + } + private fun buildStrategy(mode: LoadTimelineStrategy.Mode): LoadTimelineStrategy { return LoadTimelineStrategy( roomId = roomId, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/LoadTimelineStrategy.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/LoadTimelineStrategy.kt index a9e7b3bcdc..bb565a8d6b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/LoadTimelineStrategy.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/LoadTimelineStrategy.kt @@ -24,6 +24,8 @@ import io.realm.RealmResults import io.realm.kotlin.createObject import kotlinx.coroutines.CompletableDeferred import org.matrix.android.sdk.api.extensions.orFalse +import org.matrix.android.sdk.api.failure.Failure +import org.matrix.android.sdk.api.failure.MatrixError import org.matrix.android.sdk.api.session.room.send.SendState import org.matrix.android.sdk.api.session.room.timeline.Timeline import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent @@ -194,6 +196,10 @@ internal class LoadTimelineStrategy( getContextLatch?.await() getContextLatch = null } catch (failure: Throwable) { + if (failure is Failure.ServerError && failure.error.code == MatrixError.M_NOT_FOUND) { + // This failure is likely permanent, so handle in DefaultTimeline to restart without eventId + throw failure + } return LoadMoreResult.FAILURE } } From c44c637fbaa5be5329d480baa291a0a144272025 Mon Sep 17 00:00:00 2001 From: SpiritCroc Date: Wed, 30 Mar 2022 17:35:51 +0200 Subject: [PATCH 2/2] Also give up loading event for M_FORBIDDEN --- .../sdk/internal/session/room/timeline/LoadTimelineStrategy.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/LoadTimelineStrategy.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/LoadTimelineStrategy.kt index bb565a8d6b..42973797f3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/LoadTimelineStrategy.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/LoadTimelineStrategy.kt @@ -196,7 +196,7 @@ internal class LoadTimelineStrategy( getContextLatch?.await() getContextLatch = null } catch (failure: Throwable) { - if (failure is Failure.ServerError && failure.error.code == MatrixError.M_NOT_FOUND) { + if (failure is Failure.ServerError && failure.error.code in listOf(MatrixError.M_NOT_FOUND, MatrixError.M_FORBIDDEN)) { // This failure is likely permanent, so handle in DefaultTimeline to restart without eventId throw failure }