Load timeline without initial eventId if not found

This commit is contained in:
SpiritCroc 2022-03-29 12:45:23 +02:00
parent 0bc223cfde
commit 365c03e763
3 changed files with 24 additions and 1 deletions

1
changelog.d/5659.bugfix Normal file
View File

@ -0,0 +1 @@
Fix endless loading if the event from a permalink is not found

View File

@ -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,

View File

@ -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
}
}