Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect deserialization of sealed class #2035

Closed
pablobaldez opened this issue Sep 14, 2022 · 1 comment
Closed

Incorrect deserialization of sealed class #2035

pablobaldez opened this issue Sep 14, 2022 · 1 comment
Assignees
Labels
bug Properties (format) runtime up for grabs A good issue for external contribution

Comments

@pablobaldez
Copy link

pablobaldez commented Sep 14, 2022

Describe the bug
I'm using the kotlin serialization properties (not the json) and I'm getting MissingFieldException error when I try to decode a sealed class from a map
To Reproduce
I have a map

// my sealed classes 
@Serializable
@Keep
sealed class Odds {
    abstract val value: Long
}

@SerialName("EUROPEAN")
@Serializable
@Keep
data class European(override val value: Long) : Odds()

@SerialName("AMERICAN")
@Serializable
@Keep
data class American(override val value: Long) : Odds()


val map = mapOf("type" to "AMERICAN", "value" to 1)
val odds: Odds = Properties.decodeFromMap(map)

This is the stracktrace I have

Caused by: kotlinx.serialization.MissingFieldException: Field 'value' is required for type with serial name 'AMERICAN', but it was missing
                                                                                         	at kotlinx.serialization.internal.PluginExceptionsKt.throwMissingFieldException(PluginExceptions.kt:20)
                                                                                         	at br.com.mob1st.bet.features.competitions.domain.American.<init>(Bet.kt:36)
                                                                                         	at br.com.mob1st.bet.features.competitions.domain.American$$serializer.deserialize(Bet.kt:36)
                                                                                         	at br.com.mob1st.bet.features.competitions.domain.American$$serializer.deserialize(Bet.kt:36)
                                                                                         	at kotlinx.serialization.encoding.Decoder$DefaultImpls.decodeSerializableValue(Decoding.kt:257)
                                                                                         	at kotlinx.serialization.internal.TaggedDecoder.decodeSerializableValue(Tagged.kt:178)
                                                                                         	at kotlinx.serialization.internal.TaggedDecoder.decodeSerializableValue(Tagged.kt:207)
                                                                                         	at kotlinx.serialization.internal.TaggedDecoder$decodeSerializableElement$1.invoke(Tagged.kt:280)
                                                                                         	at kotlinx.serialization.internal.TaggedDecoder.tagBlock(Tagged.kt:297)
                                                                                         	at kotlinx.serialization.internal.TaggedDecoder.decodeSerializableElement(Tagged.kt:280)
                                                                                         	at kotlinx.serialization.encoding.CompositeDecoder$DefaultImpls.decodeSerializableElement$default(Decoding.kt:533)
                                                                                         	at kotlinx.serialization.internal.AbstractPolymorphicSerializer.deserialize(AbstractPolymorphicSerializer.kt:57)
                                                                                         	at kotlinx.serialization.encoding.Decoder$DefaultImpls.decodeSerializableValue(Decoding.kt:257)
                                                                                         	at kotlinx.serialization.internal.TaggedDecoder.decodeSerializableValue(Tagged.kt:178)
                                                                                         	at kotlinx.serialization.properties.Properties.decodeFromMap(Properties.kt:173)
                                                                                         	at br.com.mob1st.bet.features.competitions.data.ContestMapperKt$nodeBuilder$1.invoke(ContestMapper.kt:226)
                                                                                         	at br.com.mob1st.bet.features.competitions.data.ContestMapperKt$nodeBuilder$1.invoke(ContestMapper.kt:33)
                                                                                         	at br.com.mob1st.bet.features.competitions.data.CompetitionCollection.getConfrontationsById(CompetitionCollection.kt:54)
                                                                                         	at br.com.mob1st.bet.features.competitions.data.CompetitionCollection$getConfrontationsById$1.invokeSuspend(Unknown Source:12)
                                                                                         	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) 
                                                                                         	at kotlinx.coroutines.internal.ScopeCoroutine.afterResume(Scopes.kt:33) 
                                                                                         	at kotlinx.coroutines.AbstractCoroutine.resumeWith(AbstractCoroutine.kt:102) 
                                                                                         	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46) 
                                                                                         	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106) 
                                                                                         	at kotlinx.coroutines.internal.LimitedDispatcher.run(LimitedDispatcher.kt:42) 
                                                                                         	at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:95) 
                                                                                         	at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570) 
                                                                                         	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750) 
                                                                                         	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677) 
                                                                                         	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664) 

Expected behavior
The deserialization should run properly
Environment

  • Kotlin version: 1.7.0
  • Library version: 1.4.0
  • Kotlin platforms: Android
  • Gradle version: gradle-7.4
  • IDE version Android Studio dolphin
  • Other relevant context [e.g. OS version, JRE version, ... ]: I tried to debug the the lib code to figure out where are the cause of the problem, and it seems that for some reason the NamedValueDecoder are return value.value in the getTag method
@pablobaldez
Copy link
Author

important info: If I try the same thing using the kotlinx-serialization-json it works perfectly

val oddsMap = mapOf(
    "type" to JsonPrimitive("AMERICAN"),
    "value" to JsonPrimitive(1L)
)
val e = JsonObject(
    oddsMap
)
val odds: Odds = Json {
    ignoreUnknownKeys = true
}.decodeFromJsonElement(e)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Properties (format) runtime up for grabs A good issue for external contribution
Projects
None yet
Development

No branches or pull requests

3 participants