From 3f2afa4cef42450e75c150228316449e1537ddce Mon Sep 17 00:00:00 2001 From: Dominic Gunther Bauer <46312751+DominicGBauer@users.noreply.github.com> Date: Wed, 15 Jan 2025 09:56:21 +0200 Subject: [PATCH] feat: do not invalidate credentials on io error (#104) * feat: do not invalidate credentials on io error * chore: remove tests as they don't really work * chore: update changelog * chore: remove invalidation * chore: update changelog --- CHANGELOG.md | 4 +- .../kotlin/com/powersync/sync/SyncStream.kt | 8 +-- .../com/powersync/sync/SyncStreamTest.kt | 54 +++++++++++++++++++ 3 files changed, 60 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7e7c24..6008d19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,8 @@ ## 1.0.0-BETA16 -* Add `close` method to database methods - +* Add `close` method to database methods +* Throw when error is a `CancellationError` and remove invalidation for all errors in `streamingSync` catch. ## 1.0.0-BETA15 * Update powersync-sqlite-core to 0.3.8 diff --git a/core/src/commonMain/kotlin/com/powersync/sync/SyncStream.kt b/core/src/commonMain/kotlin/com/powersync/sync/SyncStream.kt index bd4dfd6..c16025a 100644 --- a/core/src/commonMain/kotlin/com/powersync/sync/SyncStream.kt +++ b/core/src/commonMain/kotlin/com/powersync/sync/SyncStream.kt @@ -96,11 +96,11 @@ internal class SyncStream( // break; // } } catch (e: Exception) { - // If the coroutine was cancelled, don't log an error - if (e !is CancellationException) { - logger.e(e) { "Error in streamingSync" } + if (e is CancellationException) { + throw e } - invalidCredentials = true + + logger.e(e) { "Error in streamingSync: $e" } status.update( downloadError = e, ) diff --git a/core/src/commonTest/kotlin/com/powersync/sync/SyncStreamTest.kt b/core/src/commonTest/kotlin/com/powersync/sync/SyncStreamTest.kt index 04b743a..8284dce 100644 --- a/core/src/commonTest/kotlin/com/powersync/sync/SyncStreamTest.kt +++ b/core/src/commonTest/kotlin/com/powersync/sync/SyncStreamTest.kt @@ -6,13 +6,17 @@ import co.touchlab.kermit.TestConfig import co.touchlab.kermit.TestLogWriter import com.powersync.bucket.BucketStorage import com.powersync.connectors.PowerSyncBackendConnector +import com.powersync.connectors.PowerSyncCredentials import com.powersync.db.crud.CrudEntry import com.powersync.db.crud.UpdateType import dev.mokkery.answering.returns import dev.mokkery.everySuspend import dev.mokkery.mock import dev.mokkery.verify +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch import kotlinx.coroutines.test.runTest +import kotlinx.coroutines.withTimeout import kotlinx.serialization.json.JsonObject import kotlin.test.BeforeTest import kotlin.test.Test @@ -112,4 +116,54 @@ class SyncStreamTest { assertEquals(Severity.Error, severity) } } + + @Test + fun testStreamingSyncBasicFlow() = + runTest { + bucketStorage = + mock { + everySuspend { getClientId() } returns "test-client-id" + everySuspend { getBucketStates() } returns emptyList() + } + + connector = + mock { + everySuspend { getCredentialsCached() } returns + PowerSyncCredentials( + token = "test-token", + userId = "test-user", + endpoint = "https://test.com", + ) + } + + syncStream = + SyncStream( + bucketStorage = bucketStorage, + connector = connector, + uploadCrud = { }, + retryDelayMs = 10, + logger = logger, + params = JsonObject(emptyMap()), + ) + + // Launch streaming sync in a coroutine that we'll cancel after verification + val job = + launch { + syncStream.streamingSync() + } + + // Wait for status to update + withTimeout(1000) { + while (!syncStream.status.connecting) { + delay(10) + } + } + + // Verify initial state + assertEquals(true, syncStream.status.connecting) + assertEquals(false, syncStream.status.connected) + + // Clean up + job.cancel() + } }