最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

kotlin - Serializer for class 'Result' is not found. Please ensure that class is marked as'@Serializable

programmeradmin3浏览0评论

I just learn ktor-client and kotlinx.Serialization for my personal project, but then I found this error.

kotlinx.serialization.SerializationException: Serializer for class 'Result' is not found.Please ensure that class is marked as '@Serializable' and that the serialization compiler plugin is applied.

build.gradle.kts (project

plugins {
    ..
    alias(libs.plugins.kotlin.serialization) apply false
}

build.gradle.kts (app)

plugins {
    ...
    alias(libs.plugins.kotlin.serialization)
}

dependencies {
    ...
    implementation(libs.kotlinx.serialization.json)
    implementation(libs.ktor.client.serialization)
    ...
}

Result.kt

sealed class Result<out Data, out Error> {
    data class Success<out Data>(val data: Data) : Result<Data, Nothing>()

    data class Failure<out Error>(val error: Error) : Result<Nothing, Error>()

    inline fun <T> fold(
        onSuccess: (Data) -> T,
        onFailure: (Error) -> T
    ) = when (this) {
        is Success -> onSuccess(data)
        is Failure -> onFailure(error)
    }
}

DTO

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class EmailListItemDto(
    @SerialName("threadId")
    val threadId: String? = null,
    @SerialName("snippet")
    val snippet: String? = null,
    @SerialName("isPromotional")
    val isPromotional: Boolean? = null,
    @SerialName("payload")
    val payload: Payload? = null,
    @SerialName("subject")
    val subject: String? = null,
    @SerialName("isImportant")
    val isImportant: Boolean? = null,
    @SerialName("id")
    val id: String? = null,
    @SerialName("hasAttachments")
    val hasAttachments: Boolean? = null,
    @SerialName("timestamp")
    val timestamp: Int? = null
)

@Serializable
data class Payload(
    @SerialName("date")
    val date: String? = null,
    @SerialName("subject")
    val subject: String? = null,
    @SerialName("from")
    val from: String? = null,
    @SerialName("profileImage")
    val profileImage: String? = null,
    @SerialName("email")
    val email: String? = null
)

Also I already tried to mark the Result and its Success and Failure class as @Serializable, but the error still there, and I tried to add these codes to proguard-rules.pro but nothing happen.

-keep class kotlinx.serialization.** { *; }
-keep class com.myPackage.Result { *; }

UPDATE

ApiService

class EmailApiServiceImpl(
    private val httpClient: HttpClient
) : EmailApiService {
    override suspend fun getEmailList(): Result<List<EmailListItemDto>, Failure> {
        return httpClient.get("/email-list").body()
    }
}

RepositoryImpl

class EmailRepositoryImpl @Inject constructor(
    private val apiService: EmailApiService,
) : EmailRepository {
    override suspend fun getEmailList(): Result<List<EmailListItemModel>, Failure> {
        return safeApiCall<List<EmailListItemDto>, List<EmailListItemModel>>(
            apiCall = { apiService.getEmailList() },
            mapper = EmailListMapper()
        )
    }
}

safeApiCall

suspend inline fun <reified T, reified R> safeApiCall(
    ioDispatcher: CoroutineDispatcher = Dispatchers.IO,
    crossinline apiCall: suspend () -> Result<T, Failure>,
    mapper: ResultMapper<T, R>
): Result<R, Failure> {
    return withContext(ioDispatcher){
        runCatching {
            val result = apiCall()

            result.fold(
                onSuccess = {
                   Success(mapper.map(it))
                },
                onFailure = {
                    Result.Failure(it)
                }
            )
        }.getOrElse { t ->
            t.toResult()
        }
    }
}

Here is the updated description while I put the usage of the Result wrapper, also there's a code for safeApiCall that just fold it into success or failure, and for the mapper it's just usual mapper that map the data model to domain model.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论