What is your use-case and why do you need this feature?
I would like to create SDK for my API, that will be able to skip unknown types from new version. For example:
@Serializable
class Response(val data: List<SomeClass>)
@Serializable
sealed class SomeClass {
@Serializable
class A(val int: Int)
@Serializable
class B(val int: Int, val string: String)
}
When SDK will be used on client and API adds class C I would like client to ignore new class. Default behavior would crash client app.
For JSON I found solution like this:
open class IgnoreSerializationErrorListSerializer<E>(private val elementSerializer: KSerializer<E>) :
KSerializer<List<E>> {
private val listSerializer = ListSerializer(elementSerializer)
override val descriptor: SerialDescriptor = listSerializer.descriptor
override fun serialize(encoder: Encoder, value: List<E>) {
listSerializer.serialize(encoder, value)
}
override fun deserialize(decoder: Decoder): List<E> = with(decoder as JsonDecoder) {
decodeJsonElement().jsonArray.mapNotNull {
try {
json.decodeFromJsonElement(elementSerializer, it)
} catch (e: SerializationException) {
null
}
}
}
}
object IgnoreUnknownResponse : IgnoreSerializationErrorListSerializer<SomeClass>(SomeClass.serializer())
Which I can then apply on response class and get expected result:
@Serializable
class Response(
@Serializable(with = IgnoreUnknownResponse::class)
val data: List<SomeClass>
)
Unfortunately it uses JsonDecoder so it won't work for Cbor ContentType
Describe the solution you'd like
Best solution would be built in ListSerializer that would ignore errors on deserialization. It is very common good practice to be "precise with things you send and general with things you receive". Maybe making ArrayListSerializer open would help to, so I could override readElement method and skip builder.insert when decode fails:
What is your use-case and why do you need this feature? I would like to create SDK for my API, that will be able to skip unknown types from new version. For example:
When SDK will be used on client and API adds class C I would like client to ignore new class. Default behavior would crash client app.
For JSON I found solution like this:
Which I can then apply on response class and get expected result:
Unfortunately it uses JsonDecoder so it won't work for Cbor ContentType
Describe the solution you'd like Best solution would be built in ListSerializer that would ignore errors on deserialization. It is very common good practice to be "precise with things you send and general with things you receive". Maybe making ArrayListSerializer open would help to, so I could override readElement method and skip builder.insert when decode fails:
I would be satisfied with some hack or workaround to make my own "IgnoreSerializationErrorListSerializer" work on Cbor / Protobuf decoders