Kotlinx.serialization: 'ignoreUnknownKeys' configuration option does not work for Enums

Created on 1 Oct 2020  路  4Comments  路  Source: Kotlin/kotlinx.serialization

Describe the bug
If you have an EnumClass and the json contains an element not present in the enum it will crash:
kotlinx.serialization.SerializationException: com.example.testingstuff.Numbers does not contain element with name 'Two'

But since i have declared ignoreUnknownKeys = true i expect it to be either null or default to something.

I did not find anything about this in the documentation.

Also is there any workaround for this?

To Reproduce

enum class Numbers {
    One
}

@Serializable
data class EnumClass(
    val enumType: Numbers? = null
)

class ExampleUnitTest {
    @Test
    fun ignoreUnknownEnum() {
        val json = Json {
            ignoreUnknownKeys = true
        }
        //This will work
        var jsonString = "{\"enumType\": \"One\" }"
        json.decodeFromString(EnumClass.serializer(), jsonString)

        //This will crash
        jsonString = "{\"enumType\": \"Two\" }"
        json.decodeFromString(EnumClass.serializer(), jsonString)
    }
}

Expected behavior
enumType becomes null or Numbers.One

Environment

  • Kotlin version: 1.4.10
  • Library version: 1.0.0-RC2
  • Kotlin platforms: Android JVM
  • Gradle version: 4.0.1
question

Most helpful comment

Currently, the only workaround is to write your own serializer.
We may consider implementing this functionality as part of coerceInputValues

Yes please. Consider this a feature request

All 4 comments

It works as expected, ignoreUnknownKeys is designed to ignore unknown _keys_, not values.
But you can use coerceInputValues = true for the very purpose you described

It works as expected, ignoreUnknownKeys is designed to ignore unknown _keys_, not values.
But you can use coerceInputValues = true for the very purpose you described

Nice that worked for the example case. But what about if it is a list of enums?

It still crashes when i change my example to this:

enum class Numbers {
    One
}

@Serializable
data class EnumClass(
    val enumType: List<Numbers?>
)

class ExampleUnitTest {
    @Test
    fun ignoreUnknownEnum() {
        val json = Json {
            ignoreUnknownKeys = true
            coerceInputValues = true
        }

        var jsonString = "{\"enumType\": [\"One\"] }"
        json.decodeFromString(EnumClass.serializer(), jsonString)

        jsonString = "{\"enumType\": [\"Two\"] }"
        json.decodeFromString(EnumClass.serializer(), jsonString)
    }
}

Currently, the only workaround is to write your own serializer.
We may consider implementing this functionality as part of coerceInputValues

Currently, the only workaround is to write your own serializer.
We may consider implementing this functionality as part of coerceInputValues

Yes please. Consider this a feature request

Was this page helpful?
0 / 5 - 0 ratings