Skip to content

Commit

Permalink
chore: improve demo upload data to handle fatal errors
Browse files Browse the repository at this point in the history
  • Loading branch information
DominicGBauer committed Dec 23, 2024
1 parent 7d46dc9 commit 12f3485
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 2 deletions.
42 changes: 42 additions & 0 deletions Demo/PowerSyncExample/PowerSync/SupabaseConnector.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,45 @@ import Supabase
import PowerSync
import AnyCodable

private struct PostgresFatalCodes {
/// Postgres Response codes that we cannot recover from by retrying.
static let fatalResponseCodes: [String] = [
// Class 22 — Data Exception
// Examples include data type mismatch.
"22...",
// Class 23 — Integrity Constraint Violation.
// Examples include NOT NULL, FOREIGN KEY and UNIQUE violations.
"23...",
// INSUFFICIENT PRIVILEGE - typically a row-level security violation
"42501"
]

static func isFatalError(_ code: String) -> Bool {
return fatalResponseCodes.contains { pattern in
code.range(of: pattern, options: [.regularExpression]) != nil
}
}

static func extractErrorCode(from error: any Error) -> String? {
// Look for code: Optional("XXXXX") pattern
let errorString = String(describing: error)
if let range = errorString.range(of: "code: Optional\\(\"([^\"]+)\"\\)", options: .regularExpression),
let codeRange = errorString[range].range(of: "\"([^\"]+)\"", options: .regularExpression) {
// Extract just the code from within the quotes
let code = errorString[codeRange].dropFirst().dropLast()
return String(code)
}
return nil
}
}


@Observable
class SupabaseConnector: PowerSyncBackendConnector {
let powerSyncEndpoint: String = Secrets.powerSyncEndpoint
let client: SupabaseClient = SupabaseClient(supabaseURL: Secrets.supabaseURL, supabaseKey: Secrets.supabaseAnonKey)
var session: Session?
private var errorCode: String?

@ObservationIgnored
private var observeAuthStateChangesTask: Task<Void, Error>?
Expand Down Expand Up @@ -76,6 +110,14 @@ class SupabaseConnector: PowerSyncBackendConnector {
_ = try await transaction.complete.invoke(p1: nil)

} catch {
if let errorCode = PostgresFatalCodes.extractErrorCode(from: error),
PostgresFatalCodes.isFatalError(errorCode) {
print("Data upload error: \(error)")
print("Discarding entry: \(lastEntry!)")
_ = try await transaction.complete.invoke(p1: nil)
return
}

print("Data upload error - retrying last entry: \(lastEntry!), \(error)")
throw error
}
Expand Down
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ This SDK is currently in a beta release it is suitable for production use, given

The easiest way to test the PowerSync Swift SDK is to run our demo application.

- [Demo/PowerSyncExample](./Demo/PowerSyncExample/README.md): A simple to-do list application demonstrating the use of the PowerSync Swift SDK using a Supabase connector.
- [Demo/PowerSyncExample](./Demo/README.md): A simple to-do list application demonstrating the use of the PowerSync Swift SDK using a Supabase connector.

## Installation

Expand Down Expand Up @@ -59,4 +59,3 @@ The PowerSync Swift SDK currently makes use of the [PowerSync Kotlin Multiplatfo
## Migration from Alpha to Beta

See these [developer notes](https://docs.powersync.com/client-sdk-references/swift#migrating-from-the-alpha-to-the-beta-sdk) if you are migrating from the alpha to the beta version of the Swift SDK.

0 comments on commit 12f3485

Please sign in to comment.