kotlinx.serialization icon indicating copy to clipboard operation
kotlinx.serialization copied to clipboard

Provide error details in case of [de]serialization failure in a custom serializer

Open LibertyPaul opened this issue 2 years ago • 2 comments

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

LibertyPaul avatar Jan 25 '23 08:01 LibertyPaul

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.

pdvrieze avatar Jan 25 '23 11:01 pdvrieze

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.

hfhbd avatar Oct 24 '23 09:10 hfhbd