kotlinx.serialization
kotlinx.serialization copied to clipboard
Provide error details in case of [de]serialization failure in a custom serializer
What is your use-case and why do you need this feature?
We are using custom serializers extensively. It is significantly more difficult to locate an incorrect value in case a custom serializer is used.
❌ Custom serializer failure. The exception does not provide any information about the incorrect field or value:
java.lang.NumberFormatException: Invalid number format: '0x'
at kotlin.text.StringsKt__StringNumberConversionsKt.numberFormatError(StringNumberConversions.kt:203)
at kotlin.text.UStringsKt.toUByte(UStrings.kt:66)
at com.company.app_name.config.serializers.ByteListAsHexSerializer.deserialize(ByteListAsHexSerializer.kt:34)
...
✅ Native serializer failure. The exception contains a detailed exception:
kotlinx.serialization.json.internal.JsonDecodingException: Unexpected JSON token at offset 661: Unexpected symbol 'a' in numeric literal at path: $.field_name
JSON input: .....: "0x00",
"field_name": "asdfgh",
"another_field_name.....
Describe the solution you'd like
kotlinx.serialization could intercept exceptions raised by custom serializers and throw it's own kotlinx.serialization.json.internal.JsonDecodingException
with the error context (field name + incorrect value) and the original exception linked to it (as cause
).
Alternatively (yet it does not look as good as the previous option), a custom serializer can be given with an access to the serialization context (field name / value / surrounding JSON) to be able to construct an appropriate error message on its own.
Environment: Kotlin: 1.8.0 / JVM Serialization plugin: 1.8.0 Serialization library: 1.4.1
I would say that the suggested alternative is a bit problematic as it would be a challenge for alternative formats. (Of course it is possible to check for a specific format in the custom serializer). But I see the point of capturing exceptions and adding context. Handling of error messages/brittle serializers is not quite at the point you'd like it to be.
I also got the same problem when using kotlinx-datetime:
@Serializable
data class MyDate(val myDate: Instant)
val invalid = """{ "myDate": "fff" }"""
Json.decodeFromString(MyDate.serializer(), invalid)
Results into this error message:
kotlinx.datetime.DateTimeFormatException: java.time.format.DateTimeParseException: Text 'fff' could not be parsed at index 0
at kotlinx.datetime.Instant$Companion.parse(Instant.kt:72)
at kotlinx.datetime.serializers.InstantIso8601Serializer.deserialize(InstantSerializers.kt:27)
at kotlinx.datetime.serializers.InstantIso8601Serializer.deserialize(InstantSerializers.kt:21)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:70)
Without any information which field is caused the exception.