From c9582ed549bdb0f392a74f37e22aebb332036e8a Mon Sep 17 00:00:00 2001 From: Dominic Date: Thu, 31 Oct 2024 13:08:13 +0200 Subject: [PATCH 1/5] chore: update supabase --- connectors/supabase/build.gradle.kts | 2 +- .../connector/supabase/SupabaseConnector.kt | 10 +++--- .../java/com/powersync/androidexample/Auth.kt | 23 ++++++++----- demos/hello-powersync/build.gradle.kts | 2 +- .../composeApp/build.gradle.kts | 32 ++++++++++++------- .../gradle/libs.versions.toml | 6 ++-- .../supabase-todolist/shared/build.gradle.kts | 31 ++++++++++++------ .../kotlin/com/powersync/demos/Auth.kt | 27 ++++++++++------ gradle/libs.versions.toml | 6 ++-- 9 files changed, 87 insertions(+), 52 deletions(-) diff --git a/connectors/supabase/build.gradle.kts b/connectors/supabase/build.gradle.kts index 37616373..ee1ac4cb 100644 --- a/connectors/supabase/build.gradle.kts +++ b/connectors/supabase/build.gradle.kts @@ -31,7 +31,7 @@ kotlin { api(project(":core")) implementation(libs.kotlinx.coroutines.core) implementation(libs.supabase.client) - api(libs.supabase.gotrue) + api(libs.supabase.auth) } } } diff --git a/connectors/supabase/src/commonMain/kotlin/com/powersync/connector/supabase/SupabaseConnector.kt b/connectors/supabase/src/commonMain/kotlin/com/powersync/connector/supabase/SupabaseConnector.kt index 024fc0eb..d9006455 100644 --- a/connectors/supabase/src/commonMain/kotlin/com/powersync/connector/supabase/SupabaseConnector.kt +++ b/connectors/supabase/src/commonMain/kotlin/com/powersync/connector/supabase/SupabaseConnector.kt @@ -6,12 +6,12 @@ import com.powersync.connectors.PowerSyncCredentials import com.powersync.db.crud.CrudEntry import com.powersync.db.crud.UpdateType import io.github.jan.supabase.SupabaseClient +import io.github.jan.supabase.auth.Auth +import io.github.jan.supabase.auth.auth +import io.github.jan.supabase.auth.providers.builtin.Email +import io.github.jan.supabase.auth.status.SessionStatus +import io.github.jan.supabase.auth.user.UserSession import io.github.jan.supabase.createSupabaseClient -import io.github.jan.supabase.gotrue.Auth -import io.github.jan.supabase.gotrue.SessionStatus -import io.github.jan.supabase.gotrue.auth -import io.github.jan.supabase.gotrue.providers.builtin.Email -import io.github.jan.supabase.gotrue.user.UserSession import io.github.jan.supabase.postgrest.Postgrest import io.github.jan.supabase.postgrest.from import kotlinx.coroutines.flow.StateFlow diff --git a/demos/android-supabase-todolist/app/src/main/java/com/powersync/androidexample/Auth.kt b/demos/android-supabase-todolist/app/src/main/java/com/powersync/androidexample/Auth.kt index 28fad731..5cb25151 100644 --- a/demos/android-supabase-todolist/app/src/main/java/com/powersync/androidexample/Auth.kt +++ b/demos/android-supabase-todolist/app/src/main/java/com/powersync/androidexample/Auth.kt @@ -5,21 +5,22 @@ import androidx.lifecycle.viewModelScope import co.touchlab.kermit.Logger import com.powersync.PowerSyncDatabase import com.powersync.connector.supabase.SupabaseConnector -import io.github.jan.supabase.gotrue.SessionStatus +import io.github.jan.supabase.auth.status.SessionStatus import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch sealed class AuthState { - data object SignedOut: AuthState() - data object SignedIn: AuthState() + data object SignedOut : AuthState() + + data object SignedIn : AuthState() } internal class AuthViewModel( private val supabase: SupabaseConnector, private val db: PowerSyncDatabase, - private val navController: NavController -): ViewModel() { + private val navController: NavController, +) : ViewModel() { private val _authState = MutableStateFlow(AuthState.SignedOut) val authState: StateFlow = _authState private val _userId = MutableStateFlow(null) @@ -27,7 +28,7 @@ internal class AuthViewModel( init { viewModelScope.launch { - supabase.sessionStatus.collect() { + supabase.sessionStatus.collect { when (it) { is SessionStatus.Authenticated -> { _authState.value = AuthState.SignedIn @@ -48,12 +49,18 @@ internal class AuthViewModel( } } - suspend fun signIn(email: String, password: String) { + suspend fun signIn( + email: String, + password: String, + ) { supabase.login(email, password) _authState.value = AuthState.SignedIn } - suspend fun signUp(email: String, password: String) { + suspend fun signUp( + email: String, + password: String, + ) { supabase.signUp(email, password) _authState.value = AuthState.SignedIn } diff --git a/demos/hello-powersync/build.gradle.kts b/demos/hello-powersync/build.gradle.kts index 99cd4dd6..4e963e4f 100644 --- a/demos/hello-powersync/build.gradle.kts +++ b/demos/hello-powersync/build.gradle.kts @@ -6,4 +6,4 @@ plugins { alias(projectLibs.plugins.kotlinMultiplatform) apply false alias(projectLibs.plugins.cocoapods) apply false alias(libs.plugins.buildKonfig) apply false -} \ No newline at end of file +} diff --git a/demos/hello-powersync/composeApp/build.gradle.kts b/demos/hello-powersync/composeApp/build.gradle.kts index 458cdc8c..de9641cc 100644 --- a/demos/hello-powersync/composeApp/build.gradle.kts +++ b/demos/hello-powersync/composeApp/build.gradle.kts @@ -1,6 +1,6 @@ +import com.codingfeline.buildkonfig.compiler.FieldSpec.Type.STRING import org.jetbrains.compose.ExperimentalComposeLibrary import java.util.Properties -import com.codingfeline.buildkonfig.compiler.FieldSpec.Type.STRING plugins { alias(projectLibs.plugins.kotlinMultiplatform) @@ -60,7 +60,10 @@ kotlin { android { namespace = "com.powersync.demos" - compileSdk = projectLibs.versions.android.compileSdk.get().toInt() + compileSdk = + projectLibs.versions.android.compileSdk + .get() + .toInt() sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") sourceSets["main"].res.srcDirs("src/androidMain/res") @@ -68,8 +71,14 @@ android { defaultConfig { applicationId = "com.powersync.demos" - minSdk = projectLibs.versions.android.minSdk.get().toInt() - targetSdk = projectLibs.versions.android.targetSdk.get().toInt() + minSdk = + projectLibs.versions.android.minSdk + .get() + .toInt() + targetSdk = + projectLibs.versions.android.targetSdk + .get() + .toInt() versionCode = 1 versionName = "1.0" } @@ -96,13 +105,14 @@ android { } } -val localProperties = Properties().apply { - try { - load(rootProject.file("local.properties").reader()) - } catch (ignored: java.io.IOException) { - throw Error("local.properties file not found") +val localProperties = + Properties().apply { + try { + load(rootProject.file("local.properties").reader()) + } catch (ignored: java.io.IOException) { + throw Error("local.properties file not found") + } } -} buildkonfig { packageName = "com.powersync.demos" @@ -124,4 +134,4 @@ buildkonfig { stringConfigField("SUPABASE_USER_EMAIL") stringConfigField("SUPABASE_USER_PASSWORD") } -} \ No newline at end of file +} diff --git a/demos/supabase-todolist/gradle/libs.versions.toml b/demos/supabase-todolist/gradle/libs.versions.toml index 24e1bf25..d765ba17 100644 --- a/demos/supabase-todolist/gradle/libs.versions.toml +++ b/demos/supabase-todolist/gradle/libs.versions.toml @@ -10,11 +10,11 @@ kotlin = "2.0.20" coroutines = "1.8.1" kotlinx-datetime = "0.5.0" kotlinx-io = "0.5.4" -ktor = "2.3.12" +ktor = "3.0.1" uuid = "0.8.2" buildKonfig = "0.15.1" -supabase = "2.6.1" +supabase = "3.0.1" junit = "4.13.2" compose = "1.6.11" @@ -52,7 +52,7 @@ ktor-serialization-json = { module = "io.ktor:ktor-serialization-kotlinx-json", kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" } supabase-client = { module = "io.github.jan-tennert.supabase:postgrest-kt", version.ref = "supabase" } -supabase-gotrue = { module = "io.github.jan-tennert.supabase:gotrue-kt", version.ref = "supabase" } +supabase-auth = { module = "io.github.jan-tennert.supabase:auth-kt", version.ref = "supabase" } androidx-core = { group = "androidx.core", name = "core-ktx", version.ref = "androidx-core" } androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "androidx-appcompat" } diff --git a/demos/supabase-todolist/shared/build.gradle.kts b/demos/supabase-todolist/shared/build.gradle.kts index ef72295b..4d1ec0a2 100644 --- a/demos/supabase-todolist/shared/build.gradle.kts +++ b/demos/supabase-todolist/shared/build.gradle.kts @@ -1,5 +1,5 @@ -import java.util.Properties import com.codingfeline.buildkonfig.compiler.FieldSpec.Type.STRING +import java.util.Properties plugins { alias(libs.plugins.kotlinMultiplatform) @@ -63,30 +63,41 @@ kotlin { android { namespace = "com.powersync.demos" - compileSdk = libs.versions.android.compileSdk.get().toInt() + compileSdk = + libs.versions.android.compileSdk + .get() + .toInt() sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") sourceSets["main"].res.srcDirs("src/androidMain/res") sourceSets["main"].resources.srcDirs("src/commonMain/resources") defaultConfig { - minSdk = libs.versions.android.minSdk.get().toInt() + minSdk = + libs.versions.android.minSdk + .get() + .toInt() } compileOptions { sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 } kotlin { - jvmToolchain(libs.versions.java.get().toInt()) + jvmToolchain( + libs.versions.java + .get() + .toInt(), + ) } } -val localProperties = Properties().apply { - try { - load(rootProject.file("local.properties").reader()) - } catch (ignored: java.io.IOException) { - throw Error("local.properties file not found") +val localProperties = + Properties().apply { + try { + load(rootProject.file("local.properties").reader()) + } catch (ignored: java.io.IOException) { + throw Error("local.properties file not found") + } } -} buildkonfig { packageName = "com.powersync.demos" diff --git a/demos/supabase-todolist/shared/src/commonMain/kotlin/com/powersync/demos/Auth.kt b/demos/supabase-todolist/shared/src/commonMain/kotlin/com/powersync/demos/Auth.kt index 28fad731..5cf5eecc 100644 --- a/demos/supabase-todolist/shared/src/commonMain/kotlin/com/powersync/demos/Auth.kt +++ b/demos/supabase-todolist/shared/src/commonMain/kotlin/com/powersync/demos/Auth.kt @@ -5,21 +5,22 @@ import androidx.lifecycle.viewModelScope import co.touchlab.kermit.Logger import com.powersync.PowerSyncDatabase import com.powersync.connector.supabase.SupabaseConnector -import io.github.jan.supabase.gotrue.SessionStatus +import io.github.jan.supabase.auth.status.SessionStatus import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch sealed class AuthState { - data object SignedOut: AuthState() - data object SignedIn: AuthState() + data object SignedOut : AuthState() + + data object SignedIn : AuthState() } internal class AuthViewModel( private val supabase: SupabaseConnector, private val db: PowerSyncDatabase, - private val navController: NavController -): ViewModel() { + private val navController: NavController, +) : ViewModel() { private val _authState = MutableStateFlow(AuthState.SignedOut) val authState: StateFlow = _authState private val _userId = MutableStateFlow(null) @@ -27,7 +28,7 @@ internal class AuthViewModel( init { viewModelScope.launch { - supabase.sessionStatus.collect() { + supabase.sessionStatus.collect { when (it) { is SessionStatus.Authenticated -> { _authState.value = AuthState.SignedIn @@ -36,8 +37,8 @@ internal class AuthViewModel( navController.navigate(Screen.Home) } - SessionStatus.LoadingFromStorage -> Logger.e("Loading from storage") - SessionStatus.NetworkError -> Logger.e("Network error") + SessionStatus.Initializing -> Logger.e("Loading from storage") + SessionStatus.RefreshFailure(cause) -> Logger.e("Network error") is SessionStatus.NotAuthenticated -> { db.disconnectAndClear() _authState.value = AuthState.SignedOut @@ -48,12 +49,18 @@ internal class AuthViewModel( } } - suspend fun signIn(email: String, password: String) { + suspend fun signIn( + email: String, + password: String, + ) { supabase.login(email, password) _authState.value = AuthState.SignedIn } - suspend fun signUp(email: String, password: String) { + suspend fun signUp( + email: String, + password: String, + ) { supabase.signUp(email, password) _authState.value = AuthState.SignedIn } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d60bc4e0..d0ae66ac 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -13,14 +13,14 @@ kotlin = "2.0.20" coroutines = "1.8.1" kotlinx-datetime = "0.5.0" kotlinx-io = "0.5.4" -ktor = "2.3.12" +ktor = "3.0.1" uuid = "0.8.2" powersync-core = "0.3.1" sqlite-android = "3.45.0" sqlDelight = "2.0.2" stately = "2.0.7" -supabase = "2.6.1" +supabase = "3.0.1" junit = "4.13.2" compose = "1.6.11" @@ -82,7 +82,7 @@ sqldelight-compilerEnv = { module = "app.cash.sqldelight:compiler-env", version. stately-concurrency = { module = "co.touchlab:stately-concurrency", version.ref = "stately" } supabase-client = { module = "io.github.jan-tennert.supabase:postgrest-kt", version.ref = "supabase" } -supabase-gotrue = { module = "io.github.jan-tennert.supabase:gotrue-kt", version.ref = "supabase" } +supabase-auth = { module = "io.github.jan-tennert.supabase:auth-kt", version.ref = "supabase" } # Sample - Android androidx-core = { group = "androidx.core", name = "core-ktx", version.ref = "androidx-core" } From 37512084105b219481cc31729c630a6f43c14ba9 Mon Sep 17 00:00:00 2001 From: DominicGBauer Date: Thu, 31 Oct 2024 14:10:43 +0200 Subject: [PATCH 2/5] chore: update supabase --- .../connector/supabase/SupabaseConnector.kt | 17 +++++++++++++++-- .../supabase-todolist/gradle/libs.versions.toml | 4 ---- .../kotlin/com/powersync/demos/Auth.kt | 8 +++++++- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/connectors/supabase/src/commonMain/kotlin/com/powersync/connector/supabase/SupabaseConnector.kt b/connectors/supabase/src/commonMain/kotlin/com/powersync/connector/supabase/SupabaseConnector.kt index d9006455..fd5c9ef7 100644 --- a/connectors/supabase/src/commonMain/kotlin/com/powersync/connector/supabase/SupabaseConnector.kt +++ b/connectors/supabase/src/commonMain/kotlin/com/powersync/connector/supabase/SupabaseConnector.kt @@ -1,5 +1,6 @@ package com.powersync.connector.supabase +import co.touchlab.kermit.Logger import com.powersync.PowerSyncDatabase import com.powersync.connectors.PowerSyncBackendConnector import com.powersync.connectors.PowerSyncCredentials @@ -12,6 +13,7 @@ import io.github.jan.supabase.auth.providers.builtin.Email import io.github.jan.supabase.auth.status.SessionStatus import io.github.jan.supabase.auth.user.UserSession import io.github.jan.supabase.createSupabaseClient +import io.github.jan.supabase.exceptions.BadRequestRestException import io.github.jan.supabase.postgrest.Postgrest import io.github.jan.supabase.postgrest.from import kotlinx.coroutines.flow.StateFlow @@ -136,8 +138,19 @@ public class SupabaseConnector( transaction.complete(null) } catch (e: Exception) { - println("Data upload error - retrying last entry: ${lastEntry!!}, $e") - throw e + when (e) { + is BadRequestRestException -> { + if (e.message?.contains("violates not-null constraint") == true) { + Logger.e("Not-null constraint violation: ${e.message}") + transaction.complete(null) + return + } + } + else -> { + Logger.e("Data upload error - retrying last entry: $lastEntry, $e") + throw e + } + } } } } diff --git a/demos/supabase-todolist/gradle/libs.versions.toml b/demos/supabase-todolist/gradle/libs.versions.toml index d765ba17..bce8228e 100644 --- a/demos/supabase-todolist/gradle/libs.versions.toml +++ b/demos/supabase-todolist/gradle/libs.versions.toml @@ -14,7 +14,6 @@ ktor = "3.0.1" uuid = "0.8.2" buildKonfig = "0.15.1" -supabase = "3.0.1" junit = "4.13.2" compose = "1.6.11" @@ -51,9 +50,6 @@ ktor-client-contentnegotiation = { module = "io.ktor:ktor-client-content-negotia ktor-serialization-json = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" } kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" } -supabase-client = { module = "io.github.jan-tennert.supabase:postgrest-kt", version.ref = "supabase" } -supabase-auth = { module = "io.github.jan-tennert.supabase:auth-kt", version.ref = "supabase" } - androidx-core = { group = "androidx.core", name = "core-ktx", version.ref = "androidx-core" } androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "androidx-appcompat" } androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activity-compose" } diff --git a/demos/supabase-todolist/shared/src/commonMain/kotlin/com/powersync/demos/Auth.kt b/demos/supabase-todolist/shared/src/commonMain/kotlin/com/powersync/demos/Auth.kt index 5cf5eecc..618de02c 100644 --- a/demos/supabase-todolist/shared/src/commonMain/kotlin/com/powersync/demos/Auth.kt +++ b/demos/supabase-todolist/shared/src/commonMain/kotlin/com/powersync/demos/Auth.kt @@ -5,6 +5,7 @@ import androidx.lifecycle.viewModelScope import co.touchlab.kermit.Logger import com.powersync.PowerSyncDatabase import com.powersync.connector.supabase.SupabaseConnector +import io.github.jan.supabase.auth.status.RefreshFailureCause import io.github.jan.supabase.auth.status.SessionStatus import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow @@ -38,7 +39,12 @@ internal class AuthViewModel( } SessionStatus.Initializing -> Logger.e("Loading from storage") - SessionStatus.RefreshFailure(cause) -> Logger.e("Network error") + is SessionStatus.RefreshFailure -> { + when (it.cause) { + is RefreshFailureCause.NetworkError -> Logger.e("Network error occurred") + is RefreshFailureCause.InternalServerError -> Logger.e("Internal server error occurred") + } + } is SessionStatus.NotAuthenticated -> { db.disconnectAndClear() _authState.value = AuthState.SignedOut From 5a8ffb2a76b0419672650ee6518f99082da2c209 Mon Sep 17 00:00:00 2001 From: DominicGBauer Date: Thu, 31 Oct 2024 16:15:29 +0200 Subject: [PATCH 3/5] chore: udpate beta --- CHANGELOG.md | 5 +++++ gradle.properties | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 18318ccc..66427844 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 1.0.0-BETA7 + +* Update supabase connector to use supabase-kt version 3 +* Handle null violation error in supabase connector + ## 1.0.0-BETA6 * Fix Custom Write Checkpoint application logic diff --git a/gradle.properties b/gradle.properties index e7d9ef39..2188d2ad 100644 --- a/gradle.properties +++ b/gradle.properties @@ -17,7 +17,7 @@ development=true RELEASE_SIGNING_ENABLED=true # Library config GROUP=com.powersync -LIBRARY_VERSION=1.0.0-BETA6 +LIBRARY_VERSION=1.0.0-BETA7 GITHUB_REPO=https://github.com/powersync-ja/powersync-kotlin.git # POM POM_URL=https://github.com/powersync-ja/powersync-kotlin/ From 3dfc27763572c9aa0fe3c045b2c47226d4c944fd Mon Sep 17 00:00:00 2001 From: DominicGBauer Date: Mon, 4 Nov 2024 11:54:27 +0200 Subject: [PATCH 4/5] feat: add check for all postgres errors --- .../connector/supabase/SupabaseConnector.kt | 68 +++++++++++++++---- 1 file changed, 55 insertions(+), 13 deletions(-) diff --git a/connectors/supabase/src/commonMain/kotlin/com/powersync/connector/supabase/SupabaseConnector.kt b/connectors/supabase/src/commonMain/kotlin/com/powersync/connector/supabase/SupabaseConnector.kt index fd5c9ef7..0e512c9d 100644 --- a/connectors/supabase/src/commonMain/kotlin/com/powersync/connector/supabase/SupabaseConnector.kt +++ b/connectors/supabase/src/commonMain/kotlin/com/powersync/connector/supabase/SupabaseConnector.kt @@ -7,24 +7,50 @@ import com.powersync.connectors.PowerSyncCredentials import com.powersync.db.crud.CrudEntry import com.powersync.db.crud.UpdateType import io.github.jan.supabase.SupabaseClient +import io.github.jan.supabase.annotations.SupabaseInternal import io.github.jan.supabase.auth.Auth import io.github.jan.supabase.auth.auth import io.github.jan.supabase.auth.providers.builtin.Email import io.github.jan.supabase.auth.status.SessionStatus import io.github.jan.supabase.auth.user.UserSession import io.github.jan.supabase.createSupabaseClient -import io.github.jan.supabase.exceptions.BadRequestRestException import io.github.jan.supabase.postgrest.Postgrest import io.github.jan.supabase.postgrest.from +import io.ktor.client.plugins.HttpSend +import io.ktor.client.plugins.plugin +import io.ktor.client.statement.bodyAsText +import io.ktor.utils.io.InternalAPI import kotlinx.coroutines.flow.StateFlow +import kotlinx.serialization.json.Json /** * Get a Supabase token to authenticate against the PowerSync instance. */ +@OptIn(SupabaseInternal::class, InternalAPI::class) public class SupabaseConnector( public val supabaseClient: SupabaseClient, public val powerSyncEndpoint: String, ) : PowerSyncBackendConnector() { + private var errorCode: String? = null + + private object PostgresFatalCodes { + // Using Regex patterns for Postgres error codes + private val FATAL_RESPONSE_CODES = + listOf( + // Class 22 — Data Exception + "^22...".toRegex(), + // Class 23 — Integrity Constraint Violation + "^23...".toRegex(), + // INSUFFICIENT PRIVILEGE + "^42501$".toRegex(), + ) + + fun isFatalError(code: String): Boolean = + FATAL_RESPONSE_CODES.any { pattern -> + pattern.matches(code) + } + } + public constructor( supabaseUrl: String, supabaseKey: String, @@ -43,6 +69,25 @@ public class SupabaseConnector( require( supabaseClient.pluginManager.getPluginOrNull(Postgrest) != null, ) { "The Postgrest plugin must be installed on the Supabase client" } + + // This retrieves the error code from the response + // as this is not accessible in the Supabase client RestException + // to handle fatal Postgres errors + supabaseClient.httpClient.httpClient.plugin(HttpSend).intercept { request -> + val resp = execute(request) + val response = resp.response + if (response.status.value == 400) { + val responseText = response.bodyAsText() + + try { + val error = Json { coerceInputValues = true }.decodeFromString>(responseText) + errorCode = error["code"] + } catch (e: Exception) { + Logger.e("Failed to parse error response: $e") + } + } + resp + } } public suspend fun login( @@ -111,6 +156,7 @@ public class SupabaseConnector( lastEntry = entry val table = supabaseClient.from(entry.table) + when (entry.op) { UpdateType.PUT -> { val data = entry.opData?.toMutableMap() ?: mutableMapOf() @@ -138,19 +184,15 @@ public class SupabaseConnector( transaction.complete(null) } catch (e: Exception) { - when (e) { - is BadRequestRestException -> { - if (e.message?.contains("violates not-null constraint") == true) { - Logger.e("Not-null constraint violation: ${e.message}") - transaction.complete(null) - return - } - } - else -> { - Logger.e("Data upload error - retrying last entry: $lastEntry, $e") - throw e - } + if (errorCode != null && PostgresFatalCodes.isFatalError(errorCode.toString())) { + Logger.e("Data upload error: ${e.message}") + Logger.e("Discarding entry: $lastEntry") + transaction.complete(null) + return } + + Logger.e("Data upload error - retrying last entry: $lastEntry, $e") + throw e } } } From 1375fff92add7f71bc18c2e460ecd77d79cbd46a Mon Sep 17 00:00:00 2001 From: DominicGBauer Date: Mon, 4 Nov 2024 11:56:03 +0200 Subject: [PATCH 5/5] docs: change changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 66427844..42e32b7e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ## 1.0.0-BETA7 * Update supabase connector to use supabase-kt version 3 -* Handle null violation error in supabase connector +* Handle postgres error codes in supabase connector ## 1.0.0-BETA6