diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/parser/favicon/FaviconFetcher.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/parser/favicon/FaviconFetcher.kt index f8ec34d49..a430f1601 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/parser/favicon/FaviconFetcher.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/parser/favicon/FaviconFetcher.kt @@ -14,6 +14,7 @@ import coil.network.HttpException import coil.request.Options import coil.size.Size import coil.size.pxOrElse +import kotlinx.coroutines.ensureActive import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.Response @@ -25,11 +26,13 @@ import org.koitharu.kotatsu.core.exceptions.CloudFlareProtectedException import org.koitharu.kotatsu.core.model.MangaSource import org.koitharu.kotatsu.core.parser.MangaRepository import org.koitharu.kotatsu.core.parser.RemoteMangaRepository +import org.koitharu.kotatsu.core.util.ext.writeAllCancellable import org.koitharu.kotatsu.local.data.CacheDir import org.koitharu.kotatsu.local.data.util.withExtraCloseable import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.util.await import java.net.HttpURLConnection +import kotlin.coroutines.coroutineContext private const val FALLBACK_SIZE = 9999 // largest icon @@ -55,13 +58,16 @@ class FaviconFetcher( options.size.height.pxOrElse { FALLBACK_SIZE }, ) var favicons = repo.getFavicons() + var lastError: Exception? = null while (favicons.isNotEmpty()) { - val icon = favicons.find(sizePx) ?: throwNSEE() + coroutineContext.ensureActive() + val icon = favicons.find(sizePx) ?: throwNSEE(lastError) val response = try { loadIcon(icon.url, mangaSource) } catch (e: CloudFlareProtectedException) { throw e } catch (e: HttpException) { + lastError = e favicons -= icon continue } @@ -75,7 +81,7 @@ class FaviconFetcher( dataSource = response.toDataSource(), ) } - throwNSEE() + throwNSEE(lastError) } private suspend fun loadIcon(url: String, source: MangaSource): Response { @@ -105,14 +111,14 @@ class FaviconFetcher( ) } - private fun writeToDiskCache(body: ResponseBody): DiskCache.Snapshot? { + private suspend fun writeToDiskCache(body: ResponseBody): DiskCache.Snapshot? { if (!options.diskCachePolicy.writeEnabled || body.contentLength() == 0L) { return null } val editor = diskCache.value?.openEditor(diskCacheKey) ?: return null try { fileSystem.write(editor.data) { - body.source().readAll(this) + writeAllCancellable(body.source()) } return editor.commitAndOpenSnapshot() } catch (e: Throwable) { @@ -154,7 +160,13 @@ class FaviconFetcher( append(height.toString()) } - private fun throwNSEE(): Nothing = throw NoSuchElementException("No favicons found") + private fun throwNSEE(lastError: Exception?): Nothing { + if (lastError != null) { + throw lastError + } else { + throw NoSuchElementException("No favicons found") + } + } class Factory( context: Context,