xxfast / KStore

A tiny Kotlin multiplatform library that assists in saving and restoring objects to and from disk using kotlinx.coroutines, kotlinx.serialisation and okio
https://xxfast.github.io/KStore/
Apache License 2.0
443 stars 14 forks source link

JsonDecodingException in VersionedCodec #80

Open shlauzer opened 7 months ago

shlauzer commented 7 months ago

We've got the non-fatal error in Crashlytics with the following stacktrace:

Non-fatal Exception: kotlinx.serialization.json.internal.JsonDecodingException Unexpected JSON token at offset 0: Expected numeric literal at path: $ JSON input: kotlinx.serialization.json.internal.JsonExceptionsKt.JsonDecodingException (JsonExceptions.kt:24) kotlinx.serialization.json.okio.OkioStreamsKt.decodeFromBufferedSource (OkioStreams.kt:65) io.github.xxfast.kstore.file.extensions.VersionedCodec.decode (KVersionedStore.kt:68) io.github.xxfast.kstore.KStore$read$2.invokeSuspend (KStore.kt:40) ...

We use KStore 0.6.0 in the similar way:

val kstore = storeOf(
    filePath = "$storePath/application_$applicationId.json",
    version = 0,
    enableCache = true,
    json = json
)

kstore.update {
   ...
}

where storePath is application.applicationContext.filesDir.path + "/cross_sell"

It looks like a problem in version file reading: https://github.com/xxfast/KStore/blob/0.6.0/kstore-file/src/commonMain/kotlin/io/github/xxfast/kstore/file/extensions/KVersionedStore.kt#L67C33-L68C1. Have you any ideas?

Also I see that you are going to save version to file metadata instead. Do you have any plans?

xxfast commented 7 months ago

Hi @shlauzer. Is there a reason you are using the KVersionedStore without a migration plan? If you don't wish to version, you can use the regular factory method documented here

As for the crash - it looks like the JSON file is malformed. I assume this was because the coroutine context was cancelled amid a write operation. This could be fixed in #77 but further investigation is needed.

shlauzer commented 6 months ago

Hi @xxfast. Actually we don't need versioning in this moment and we can use storeOf with FileCodec. But I have a question about it. If we still change our class(e.g. add some new fields), will KStore return default value or throw exception?

xxfast commented 6 months ago

@shlauzer depends.

Refer to this doc for binary compatible migrations https://xxfast.github.io/KStore/using-versioning.html#binary-incompatible-changes

shlauzer commented 6 months ago

@xxfast As far as I understand we still need VersiondedCodec. If we decide to change our model we will be able to catch our jsonElement with version = 0 and migrate it manually.