Raffly Pohan
Raffly Pohan

Reputation: 1

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

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.

Upvotes: 0

Views: 36

Answers (0)

Related Questions