Bienvenido, me llamo Luis y hoy les traigo este nuevo post.
En un mundo perfecto, el consumidor y el productor de una API siempre estarían sincronizados, solo cambiando entre sí y adhiriéndose a los contratos más estrictos. Por desgracia, vivimos en el mundo real y ayuda ser un poco pesimista cuando el control de los datos está fuera de su alcance.
Si usted es el consumidor de una API, a veces puede haber una alternativa razonable si la deserialización sale terriblemente mal. En otras palabras, queremos un KSerializer
que volverá a algún valor predeterminado si falla la deserialización:
fun <T> KSerializer<T>.fallback(value: T) = object : KSerializer<T> by this { override fun deserialize(decoder: Decoder): T { check(decoder is JsonDecoder) { "This deserializer only supports deserializing JSON" } return try { decoder.json.decodeFromJsonElement(this@fallback, decoder.decodeJsonElement()) } catch (throwable: Throwable) { // Deserialization failed! Falling back, but you should // log the exception in case it shouldn't be happening. value } } }
Esta extensión de KSerializer
se basa en gran medida en KSerializer.nullable
: aumenta un existente KSerializer
con un poco de funcionalidad adicional. En este caso, envolvemos la llamada de deserialización en un try/catch
, devolviendo el valor predeterminado proporcionado value
si se produjo alguna excepción durante la deserialización.
Ahora, poniéndolo en uso: por razones de compatibilidad con versiones posteriores, puede ser útil permitir que enums tome un valor predeterminado UNKNOWN
valor. Como sugiere el nombre, queremos que cualquier valor desconocido se convierta en UNKNOWN
en lugar de provocar un error:
@Serializable enum class TestEnum { UNKNOWN, ALPHA, BETA, GAMMA, DELTA } val fallbackSerializer = TestEnum.serializer().fallback(TestEnum.UNKNOWN)
Con el serializador alternativo anterior, ¡eso es todo!
Añadir comentario