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.
This commit is contained in:
MajorTanya
2026-03-26 10:22:37 +01:00
committed by GitHub
parent fa197a4ab2
commit af4f17efc5
3 changed files with 22 additions and 2 deletions
+2
View File
@@ -11,6 +11,8 @@ The format is a modified version of [Keep a Changelog](https://keepachangelog.co
- `Other` - for technical stuff.
## [Unreleased]
### Improved
- Show informative error when trying to add unapproved titles to list on MAL ([@MajorTanya](https://github.com/MajorTanya)) ([#3155](https://github.com/mihonapp/mihon/pull/3155))
## [v0.19.7] - 2026-03-23
Same as v0.19.6
@@ -12,7 +12,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
@@ -122,8 +124,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<MALListItemStatus>()
.let { parseMangaItem(it, track) }
}
@@ -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")