Cursor Exceptions and Type Casts #23
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Overview
Cursor Exceptions
We currently support a SQL query cursor callback, which can throw exceptions if there are issues processing the result columns.
For example:
In the above query, if the
fakecolumn
does not exist, an exception would be thrown during the mapping phase.The current implementation uses a forced unwrap (
try!
) during the cursor's invocation. This could lead to a runtime crash if an exception occurs during the mapping process. Errors thrown in the cursor should propagate to the relevant execution method (such as get in the above example).Unfortunately, throwing exceptions in a Swift callback passed internally to the Kotlin SDK is quite tricky. While we've managed to achieve this for read and write transactions here, the current method could potentially break compatibility with the existing Kotlin SDK's mapper parameter.
At present, we wrap the Kotlin SDK PowerSyncDatabase client directly in the Swift SDK, forcing us to use the "public" Kotlin SDK methods in Swift. Ideally, in the future, we would split the Kotlin SDK into smaller components and use the internals directly (with some modifications) to better accommodate Swift-specific behavior.
This PR implements a workaround by intercepting the mapper provided to the Kotlin SDK. Exceptions are tracked and manually propagated. Although this isn't the ideal solution, it works with the current setup. A better approach could be possible once the proposal above is implemented.
Type Casting
The Kotlin SDK query methods (
get
,execute
, etc.) returnAny
after being processed by SKIEE. Currently, we explicitly cast the return type to the one provided by the mapper usingas!
. This forcedas!
cast can result in a runtime crash if there is an issue with the casting. While the cast should be safe in most cases, for consistency, we've now added safeguards to catch any potential casting errors and throw an exception that can be handled.Formatting
I ran the modified files through
swiftformat
to clean up the code, which resulted in some formatting improvements.