Track errors in VoiceMessagePresenter (#1667)

Story: https://github.com/vector-im/element-meta/issues/2085
This commit is contained in:
Marco Romano 2023-10-27 17:23:53 +02:00 committed by GitHub
parent c3cbf4de96
commit 81122ec33b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 28 additions and 1 deletions

View file

@ -23,4 +23,7 @@ internal sealed class VoiceMessageException : Exception() {
data class PermissionMissing(
override val message: String?, override val cause: Throwable?
) : VoiceMessageException()
data class PlayMessageError(
override val message: String?, override val cause: Throwable?
) : VoiceMessageException()
}

View file

@ -33,11 +33,13 @@ import dagger.multibindings.IntoMap
import io.element.android.features.messages.impl.timeline.di.TimelineItemEventContentKey
import io.element.android.features.messages.impl.timeline.di.TimelineItemPresenterFactory
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemVoiceContent
import io.element.android.features.messages.impl.voicemessages.VoiceMessageException
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.architecture.runUpdatingState
import io.element.android.libraries.di.RoomScope
import io.element.android.libraries.ui.utils.time.formatShort
import io.element.android.services.analytics.api.AnalyticsService
import kotlinx.coroutines.launch
import kotlin.time.Duration.Companion.milliseconds
@ -52,6 +54,7 @@ interface VoiceMessagePresenterModule {
class VoiceMessagePresenter @AssistedInject constructor(
voiceMessagePlayerFactory: VoiceMessagePlayer.Factory,
private val analyticsService: AnalyticsService,
@Assisted private val content: TimelineItemVoiceContent,
) : Presenter<VoiceMessageState> {
@ -102,7 +105,18 @@ class VoiceMessagePresenter @AssistedInject constructor(
if (playerState.isPlaying) {
player.pause()
} else {
scope.launch { play.runUpdatingState { player.play() } }
scope.launch {
play.runUpdatingState(
errorTransform = {
analyticsService.trackError(
VoiceMessageException.PlayMessageError("Error while trying to play voice message", it)
)
it
},
) {
player.play()
}
}
}
}
is VoiceMessageEvents.Seek -> {

View file

@ -22,12 +22,15 @@ import app.cash.turbine.test
import com.google.common.truth.Truth
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemVoiceContent
import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemVoiceContent
import io.element.android.features.messages.impl.voicemessages.VoiceMessageException
import io.element.android.features.messages.impl.voicemessages.timeline.DefaultVoiceMessagePlayer
import io.element.android.features.messages.impl.voicemessages.timeline.VoiceMessageEvents
import io.element.android.features.messages.impl.voicemessages.timeline.VoiceMessageMediaRepo
import io.element.android.features.messages.impl.voicemessages.timeline.VoiceMessagePresenter
import io.element.android.features.messages.impl.voicemessages.timeline.VoiceMessageState
import io.element.android.libraries.mediaplayer.test.FakeMediaPlayer
import io.element.android.services.analytics.api.AnalyticsService
import io.element.android.services.analytics.test.FakeAnalyticsService
import kotlinx.coroutines.test.runTest
import org.junit.Test
@ -77,8 +80,10 @@ class VoiceMessagePresenterTest {
@Test
fun `pressing play downloads and fails`() = runTest {
val analyticsService = FakeAnalyticsService()
val presenter = createVoiceMessagePresenter(
voiceMessageMediaRepo = FakeVoiceMessageMediaRepo().apply { shouldFail = true },
analyticsService = analyticsService,
content = aTimelineItemVoiceContent(durationMs = 2_000),
)
moleculeFlow(RecompositionMode.Immediate) {
@ -102,6 +107,9 @@ class VoiceMessagePresenterTest {
Truth.assertThat(it.progress).isEqualTo(0f)
Truth.assertThat(it.time).isEqualTo("0:02")
}
analyticsService.trackedErrors.first().also {
Truth.assertThat(it).isInstanceOf(VoiceMessageException.PlayMessageError::class.java)
}
}
}
@ -190,6 +198,7 @@ class VoiceMessagePresenterTest {
fun createVoiceMessagePresenter(
voiceMessageMediaRepo: VoiceMessageMediaRepo = FakeVoiceMessageMediaRepo(),
analyticsService: AnalyticsService = FakeAnalyticsService(),
content: TimelineItemVoiceContent = aTimelineItemVoiceContent(),
) = VoiceMessagePresenter(
voiceMessagePlayerFactory = { eventId, mediaSource, mimeType, body ->
@ -202,5 +211,6 @@ fun createVoiceMessagePresenter(
body = body
)
},
analyticsService = analyticsService,
content = content,
)