feat: Handle error when downloading and writing torrent file

Signed-off-by: prajwalch <prajwal.chapagain58@gmail.com>
This commit is contained in:
prajwalch
2026-03-27 20:41:06 +05:45
parent 8c4ea8e60f
commit e9acfc8428
4 changed files with 49 additions and 8 deletions
@@ -5,11 +5,13 @@ import com.prajwalch.torrentsearch.data.repository.TorrentsRepository
import dagger.hilt.android.scopes.ViewModelScoped
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.receiveAsFlow
import java.io.IOException
import java.io.OutputStream
import javax.inject.Inject
@@ -24,7 +26,11 @@ sealed interface TorrentFileDownloadState {
sealed interface TorrentFileDownloadEvent {
data class ReadyToWrite(val fileName: String) : TorrentFileDownloadEvent
data class DownloadFailed(val message: String?) : TorrentFileDownloadEvent
data object WriteSucceed : TorrentFileDownloadEvent
data class WriteFailed(val message: String?) : TorrentFileDownloadEvent
}
@ViewModelScoped
@@ -41,22 +47,33 @@ class TorrentFileDownloader @Inject constructor(
suspend fun downloadFile(url: String, fileName: String) {
reset()
_state.value = TorrentFileDownloadState.Downloading
pendingFileId = torrentsRepository.downloadTorrentFile(url = url)
_events.send(TorrentFileDownloadEvent.ReadyToWrite(fileName))
_state.value = TorrentFileDownloadState.Empty
try {
pendingFileId = torrentsRepository.downloadTorrentFile(url)
_events.send(TorrentFileDownloadEvent.ReadyToWrite(fileName))
} catch (e: CancellationException) {
// Never catch this.
throw e
} catch (e: Throwable) {
_events.send(TorrentFileDownloadEvent.DownloadFailed(e.message))
} finally {
_state.value = TorrentFileDownloadState.Empty
}
}
suspend fun writeFile(outputStream: OutputStream) {
val pendingFileId = pendingFileId ?: return
_state.value = TorrentFileDownloadState.Writing
torrentsRepository.writeTorrentFile(fileId = pendingFileId, outputStream = outputStream)
_events.send(TorrentFileDownloadEvent.WriteSucceed)
reset()
try {
torrentsRepository.writeTorrentFile(pendingFileId, outputStream)
_events.send(TorrentFileDownloadEvent.WriteSucceed)
} catch (e: IOException) {
_events.send(TorrentFileDownloadEvent.WriteFailed(e.message))
} finally {
reset()
}
}
fun reset() {
@@ -34,8 +34,10 @@ fun TorrentFileDownloadEffect(
}
val fileDownloadingMessage = stringResource(R.string.torrent_file_downloading_message)
val fileDownloadError = stringResource(R.string.torrent_file_download_error)
val fileSavingMessage = stringResource(R.string.torrent_file_saving_message)
val fileSavedMessage = stringResource(R.string.torrent_file_saved_message)
val fileSaveError = stringResource(R.string.torrent_file_save_error)
LaunchedEffect(Unit) {
events.collect { event ->
@@ -44,9 +46,25 @@ fun TorrentFileDownloadEffect(
createTorrentFileLauncher.launch(event.fileName)
}
is TorrentFileDownloadEvent.DownloadFailed -> {
val message = event.message
?.let { "$fileDownloadError: $it" }
?: fileDownloadError
snackbarHostState.showSnackbar(message = message)
}
TorrentFileDownloadEvent.WriteSucceed -> {
snackbarHostState.showSnackbar(message = fileSavedMessage)
}
is TorrentFileDownloadEvent.WriteFailed -> {
val message = event.message
?.let { "$fileSaveError: $it" }
?: fileSaveError
snackbarHostState.showSnackbar(message = message)
}
}
}
}
@@ -0,0 +1,4 @@
package com.prajwalch.torrentsearch.util
object TorrentUtils {
}
+2
View File
@@ -39,8 +39,10 @@
<string name="torznab_conn_check_result_unexpected_error">Unexpected error</string>
<string name="torrent_file_downloading_message">Downloading torrent file…</string>
<string name="torrent_file_download_error">Download failed</string>
<string name="torrent_file_saving_message">Saving torrent file…</string>
<string name="torrent_file_saved_message">Torrent file saved</string>
<string name="torrent_file_save_error">Torrent file save failed</string>
<string name="crash_screen_title">Oops!</string>
<string name="crash_screen_subtitle">