From 72c091d31708398b349cbf7f61de3e5ba2f12c6e Mon Sep 17 00:00:00 2001 From: MajorTanya <39014446+MajorTanya@users.noreply.github.com> Date: Thu, 26 Mar 2026 10:22:37 +0100 Subject: [PATCH] Add informative error for unapproved MAL titles (#3155) MAL has a concept of "titles waiting for approval". These titles cannot be added to user lists, but they do show up on the website and crucially, in search results. However, trying to add such an "unapproved" title will return a 400 error response with the error "invalid_content". Previously, the awaitSuccess() call would mean the generic "HTTP 400" toast would be shown. Now, a dedicated informative error message is shown instead. # Conflicts: # CHANGELOG.md --- .../data/track/myanimelist/MyAnimeListApi.kt | 21 +++++++++++++++++-- .../myanimelist/MyAnimeListInterceptor.kt | 1 + 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeListApi.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeListApi.kt index b90391ae6..c46b7faa3 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeListApi.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeListApi.kt @@ -14,7 +14,9 @@ import eu.kanade.tachiyomi.data.track.myanimelist.dto.MALSearchResult import eu.kanade.tachiyomi.data.track.myanimelist.dto.MALUser import eu.kanade.tachiyomi.network.DELETE import eu.kanade.tachiyomi.network.GET +import eu.kanade.tachiyomi.network.HttpException import eu.kanade.tachiyomi.network.POST +import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.network.awaitSuccess import eu.kanade.tachiyomi.network.parseAs import eu.kanade.tachiyomi.util.PkceUtil @@ -124,8 +126,23 @@ class MyAnimeListApi( .put(formBodyBuilder.build()) .build() with(json) { - authClient.newCall(request) - .awaitSuccess() + val response = authClient + .newCall(request) + .await() + + if (!response.isSuccessful) { + if (response.body.string().contains("invalid_content")) { + // MAL returns unapproved titles in search but does not allow adding them to the list + // returns 400 with this body: {"message":"Invalid content","error":"invalid_content"} + // These unapproved titles cannot be filtered out in search and are also returned by the + // endpoint we use for id prefix search + throw MALTitleNotApproved() + } else { + throw HttpException(response.code) + } + } + + response .parseAs() .let { parseMangaItem(it, track) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeListInterceptor.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeListInterceptor.kt index 7364a248d..b93276115 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeListInterceptor.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeListInterceptor.kt @@ -80,5 +80,6 @@ class MyAnimeListInterceptor(private val myanimelist: MyAnimeList) : Interceptor } } +class MALTitleNotApproved : IOException("MAL: This title can't be added because it is waiting for approval.") class MALTokenRefreshFailed : IOException("MAL: Failed to refresh account token") class MALTokenExpired : IOException("MAL: Login has expired")