Ignore non-existent galleries during favorites sync
This commit is contained in:
parent
98ac8a69c2
commit
77c07d13c0
@ -10,7 +10,11 @@ import rx.Producer
|
||||
import rx.Subscription
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
|
||||
fun Call.asObservable(): Observable<Response> {
|
||||
fun Call.asObservableWithAsyncStacktrace(): Observable<Pair<Exception, Response>> {
|
||||
// Record stacktrace at creation time for easier debugging
|
||||
// asObservable is involved in a lot of crashes so this is worth the performance hit
|
||||
val asyncStackTrace = Exception("Async stacktrace")
|
||||
|
||||
return Observable.unsafeCreate { subscriber ->
|
||||
// Since Call is a one-shot type, clone it for each new subscriber.
|
||||
val call = clone()
|
||||
@ -23,12 +27,12 @@ fun Call.asObservable(): Observable<Response> {
|
||||
try {
|
||||
val response = call.execute()
|
||||
if (!subscriber.isUnsubscribed) {
|
||||
subscriber.onNext(response)
|
||||
subscriber.onNext(asyncStackTrace to response)
|
||||
subscriber.onCompleted()
|
||||
}
|
||||
} catch (error: Exception) {
|
||||
if (!subscriber.isUnsubscribed) {
|
||||
subscriber.onError(error)
|
||||
subscriber.onError(error.withRootCause(asyncStackTrace))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -47,19 +51,14 @@ fun Call.asObservable(): Observable<Response> {
|
||||
}
|
||||
}
|
||||
|
||||
fun Call.asObservableSuccess(): Observable<Response> {
|
||||
// Record stacktrace at creation time for easier debugging
|
||||
// asObservable is involved in a lot of crashes so this is worth the performance hit
|
||||
val asyncStackTrace = Exception("Async stacktrace")
|
||||
fun Call.asObservable() = asObservableWithAsyncStacktrace().map { it.second }
|
||||
|
||||
return asObservable().doOnNext { response ->
|
||||
fun Call.asObservableSuccess(): Observable<Response> {
|
||||
return asObservableWithAsyncStacktrace().map { (asyncStacktrace, response) ->
|
||||
if (!response.isSuccessful) {
|
||||
response.close()
|
||||
throw Exception("HTTP error ${response.code()}")
|
||||
}
|
||||
}.onErrorReturn {
|
||||
// Set root cause to async stacktrace and throw again
|
||||
throw it.withRootCause(asyncStackTrace)
|
||||
throw Exception("HTTP error ${response.code()}", asyncStacktrace)
|
||||
} else response
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@ import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.network.asObservableSuccess
|
||||
import eu.kanade.tachiyomi.network.asObservableWithAsyncStacktrace
|
||||
import eu.kanade.tachiyomi.source.model.*
|
||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||
import eu.kanade.tachiyomi.source.online.LewdSource
|
||||
@ -32,6 +33,7 @@ import uy.kohesive.injekt.injectLazy
|
||||
import java.net.URLEncoder
|
||||
import java.util.*
|
||||
import exh.metadata.metadata.base.RaisedTag
|
||||
import java.lang.RuntimeException
|
||||
|
||||
class EHentai(override val id: Long,
|
||||
val exh: Boolean,
|
||||
@ -236,11 +238,21 @@ class EHentai(override val id: Long,
|
||||
*/
|
||||
override fun fetchMangaDetails(manga: SManga): Observable<SManga> {
|
||||
return client.newCall(mangaDetailsRequest(manga))
|
||||
.asObservableSuccess()
|
||||
.flatMap {
|
||||
parseToManga(manga, it).andThen(Observable.just(manga.apply {
|
||||
initialized = true
|
||||
}))
|
||||
.asObservableWithAsyncStacktrace()
|
||||
.flatMap { (stacktrace, response) ->
|
||||
if(response.isSuccessful) {
|
||||
parseToManga(manga, response).andThen(Observable.just(manga.apply {
|
||||
initialized = true
|
||||
}))
|
||||
} else {
|
||||
response.close()
|
||||
|
||||
if(response.code() == 404) {
|
||||
throw GalleryNotFoundException(stacktrace)
|
||||
} else {
|
||||
throw Exception("HTTP error ${response.code()}", stacktrace)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -522,6 +534,8 @@ class EHentai(override val id: Long,
|
||||
else
|
||||
"E-Hentai"
|
||||
|
||||
class GalleryNotFoundException(cause: Throwable): RuntimeException("Gallery not found!", cause)
|
||||
|
||||
companion object {
|
||||
private const val QUERY_PREFIX = "?f_apply=Apply+Filter"
|
||||
private const val TR_SUFFIX = "TR"
|
||||
|
@ -10,6 +10,7 @@ import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.network.NetworkHelper
|
||||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.source.online.all.EHentai
|
||||
import eu.kanade.tachiyomi.util.syncChaptersWithSource
|
||||
import exh.metadata.metadata.EHentaiSearchMetadata
|
||||
import okhttp3.MediaType
|
||||
@ -186,6 +187,11 @@ class GalleryAdder {
|
||||
return GalleryAddEvent.Success(url, manga)
|
||||
} catch(e: Exception) {
|
||||
XLog.w("Could not add gallery!", e)
|
||||
|
||||
if(e is EHentai.GalleryNotFoundException) {
|
||||
return GalleryAddEvent.Fail.NotFound(url)
|
||||
}
|
||||
|
||||
return GalleryAddEvent.Fail.Error(url,
|
||||
((e.message ?: "Unknown error!") + " (Gallery: $url)").trim())
|
||||
}
|
||||
@ -223,7 +229,10 @@ sealed class GalleryAddEvent {
|
||||
override val logMessage = "Unknown gallery type for gallery: $galleryUrl"
|
||||
}
|
||||
|
||||
class Error(override val galleryUrl: String,
|
||||
open class Error(override val galleryUrl: String,
|
||||
override val logMessage: String): Fail()
|
||||
|
||||
class NotFound(galleryUrl: String):
|
||||
Error(galleryUrl, "Gallery does not exist: $galleryUrl")
|
||||
}
|
||||
}
|
@ -323,6 +323,12 @@ class FavoritesSyncHelper(val context: Context) {
|
||||
EXH_SOURCE_ID)
|
||||
|
||||
if(result is GalleryAddEvent.Fail) {
|
||||
if(result is GalleryAddEvent.Fail.NotFound) {
|
||||
XLog.e("Remote gallery does not exist, skipping: %s!", it.getUrl())
|
||||
// Skip this gallery, it no longer exists
|
||||
return@forEachIndexed
|
||||
}
|
||||
|
||||
val errorString = "Failed to add gallery to local database: " + when (result) {
|
||||
is GalleryAddEvent.Fail.Error -> "'${it.title}' ${result.logMessage}"
|
||||
is GalleryAddEvent.Fail.UnknownType -> "'${it.title}' (${result.galleryUrl}) is not a valid gallery!"
|
||||
|
@ -43,7 +43,6 @@ class BatchAddPresenter: BasePresenter<BatchAddController>() {
|
||||
eventRelay?.call((when (result) {
|
||||
is GalleryAddEvent.Success -> "[OK]"
|
||||
is GalleryAddEvent.Fail -> "[ERROR]"
|
||||
else -> "[???]"
|
||||
}) + " " + result.logMessage)
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user