toast a friendly message for playback connection errors

Map the Media3 network/HTTP error codes to readable text and show it as a toast, instead of leaving an opaque ERR_ code on the now playing screen.
This commit is contained in:
austinried
2026-10-04 00:29:59 +00:00
parent 258dde6c86
commit 7fb832e116
5 changed files with 43 additions and 4 deletions
@@ -1,6 +1,7 @@
package com.subtracks.playback
import android.content.Context
import androidx.media3.common.PlaybackException
import androidx.room3.Room
import androidx.sqlite.driver.bundled.BundledSQLiteDriver
import androidx.test.core.app.ApplicationProvider
@@ -45,6 +46,7 @@ class PlaybackControllerTest {
private lateinit var queues: QueueRepository
private lateinit var handle: FakePlayerHandle
private lateinit var controller: PlaybackController
private val messages = CopyOnWriteArrayList<String>()
@Before
fun setUp() {
@@ -59,7 +61,8 @@ class PlaybackControllerTest {
sources = SourceRepository(db, OkHttpClient(), prefs, networkMode = networkMode)
queues = QueueRepository(db)
handle = FakePlayerHandle()
controller = PlaybackController(sources, queues, FakePlayerConnection(handle), dispatcher = dispatcher)
controller =
PlaybackController(sources, queues, FakePlayerConnection(handle), showMessage = { messages += it }, dispatcher = dispatcher)
}
@After
@@ -299,6 +302,29 @@ class PlaybackControllerTest {
assertEquals(null, controller.state.value.error)
}
@Test
fun playbackErrorsAreShownAsAToast() {
seedAlbum(3, sourceId = 1)
controller.playAlbum(1, "al1", 0)
await { handle.operations.contains("play") }
handle.fail("Can't reach the server. Check your connection.")
await { messages.isNotEmpty() }
assertEquals(listOf("Can't reach the server. Check your connection."), messages.toList())
}
@Test
fun networkErrorsAreReportedWithAFriendlyMessage() {
val failed = PlaybackException("net", null, PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_FAILED)
val timeout = PlaybackException("net", null, PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_TIMEOUT)
val refused = PlaybackException("http", null, PlaybackException.ERROR_CODE_IO_BAD_HTTP_STATUS)
assertEquals("Can't reach the server. Check your connection.", playbackErrorMessage(failed))
assertEquals("Can't reach the server. Check your connection.", playbackErrorMessage(timeout))
assertEquals("The server refused to stream this track.", playbackErrorMessage(refused))
}
@Test
fun startingAnEmptyQueueStopsThePlayer() {
seedAlbum(3, sourceId = 1)
@@ -51,7 +51,7 @@ class QueueViewModelTest {
.build()
val sources = SourceRepository(db, OkHttpClient(), fakeUserPreferences())
queues = QueueRepository(db)
controller = PlaybackController(sources, queues, FakePlayerConnection(FakePlayerHandle()), dispatcher)
controller = PlaybackController(sources, queues, FakePlayerConnection(FakePlayerHandle()), dispatcher = dispatcher)
viewModel = QueueViewModel(queues, controller)
}