-
-
Notifications
You must be signed in to change notification settings - Fork 813
Open
Labels
Description
I start a task that writes to a database queue asynchronously using:
let task = Task {
try await queue.write {
...
try Task.checkCancellation()
...
}
}I'm attempting to cancel the task using
task.cancel()and the app crashes with the following error:
GRDB/SerializedDatabase.swift:261: Fatal error: A transaction has been left opened at the end of a database access
I only get this fatal error from GRDB when the task is cancelled. The write transaction is rolled back correctly when I throw an application-defined error from the closure passed to the database writer's write(_:) function:
let task = Task {
try await queue.write {
...
throw AppError.oops
...
}
}According to the GRDB documentation for DatabaseWriter's func write(_:) async throws, cancellation of a task performing a write is legal and supported:
extension DatabaseWriter {
/// ...
/// - throws: Any ``DatabaseError`` that happens while establishing the
/// database access, or the error thrown by `updates`, or
/// `CancellationError` if the task is cancelled.
public func write<T: Sendable>(
_ updates: @Sendable (Database) throws -> T
) async throws -> T
}Is there something I should be doing to handle cancellation errors in asynchronous database read or write closures?
GRDB version: 7.8.0.