From e9acfc8428643e393b7503406cce10c53d4874b0 Mon Sep 17 00:00:00 2001 From: prajwalch Date: Fri, 27 Mar 2026 20:41:06 +0545 Subject: [PATCH] feat: Handle error when downloading and writing torrent file Signed-off-by: prajwalch --- .../TorrentFileDownloader.kt | 33 ++++++++++++++----- .../ui/TorrentFileDownloadEffect.kt | 18 ++++++++++ .../torrentsearch/util/TorrentUtils.kt | 4 +++ app/src/main/res/values/strings.xml | 2 ++ 4 files changed, 49 insertions(+), 8 deletions(-) create mode 100644 app/src/main/kotlin/com/prajwalch/torrentsearch/util/TorrentUtils.kt diff --git a/app/src/main/kotlin/com/prajwalch/torrentsearch/torrentfiledownloader/TorrentFileDownloader.kt b/app/src/main/kotlin/com/prajwalch/torrentsearch/torrentfiledownloader/TorrentFileDownloader.kt index 660abd52..85f3edd9 100644 --- a/app/src/main/kotlin/com/prajwalch/torrentsearch/torrentfiledownloader/TorrentFileDownloader.kt +++ b/app/src/main/kotlin/com/prajwalch/torrentsearch/torrentfiledownloader/TorrentFileDownloader.kt @@ -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() { diff --git a/app/src/main/kotlin/com/prajwalch/torrentsearch/ui/TorrentFileDownloadEffect.kt b/app/src/main/kotlin/com/prajwalch/torrentsearch/ui/TorrentFileDownloadEffect.kt index 7131fddf..e3d30171 100644 --- a/app/src/main/kotlin/com/prajwalch/torrentsearch/ui/TorrentFileDownloadEffect.kt +++ b/app/src/main/kotlin/com/prajwalch/torrentsearch/ui/TorrentFileDownloadEffect.kt @@ -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) + } } } } diff --git a/app/src/main/kotlin/com/prajwalch/torrentsearch/util/TorrentUtils.kt b/app/src/main/kotlin/com/prajwalch/torrentsearch/util/TorrentUtils.kt new file mode 100644 index 00000000..5615e0a1 --- /dev/null +++ b/app/src/main/kotlin/com/prajwalch/torrentsearch/util/TorrentUtils.kt @@ -0,0 +1,4 @@ +package com.prajwalch.torrentsearch.util + +object TorrentUtils { +} \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7db6dd72..4f08e6c3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -39,8 +39,10 @@ Unexpected error Downloading torrent file… + Download failed Saving torrent file… Torrent file saved + Torrent file save failed Oops!