Skip to content

Commit 80c15c6

Browse files
Fix a crash when an observation is quickly cancelled
1 parent 9014b3e commit 80c15c6

File tree

1 file changed

+9
-8
lines changed

1 file changed

+9
-8
lines changed

GRDB/ValueObservation/ValueWriteOnlyObserver.swift

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,10 @@ extension ValueWriteOnlyObserver {
198198
// from a database access.
199199
try writer.unsafeReentrantWrite { db in
200200
// Fetch & Start observing the database
201-
let fetchedValue = try fetchAndStartObservation(db)
201+
guard let fetchedValue = try fetchAndStartObservation(db) else {
202+
// Likely a GRDB bug
203+
fatalError("can't start a cancelled or failed observation")
204+
}
202205

203206
// Reduce
204207
return reduceQueue.sync {
@@ -218,12 +221,11 @@ extension ValueWriteOnlyObserver {
218221
// Start from a write access, so that self can register as a
219222
// transaction observer.
220223
writer.asyncWriteWithoutTransaction { db in
221-
let isNotifying = self.lock.synchronized { self.notificationCallbacks != nil }
222-
guard isNotifying else { return /* Cancelled */ }
223-
224224
do {
225225
// Fetch & Start observing the database
226-
let fetchedValue = try self.fetchAndStartObservation(db)
226+
guard let fetchedValue = try self.fetchAndStartObservation(db) else {
227+
return /* Cancelled */
228+
}
227229

228230
// Reduce
229231
//
@@ -260,14 +262,13 @@ extension ValueWriteOnlyObserver {
260262
/// By grouping the initial fetch and the beginning of observation in a
261263
/// single database access, we are sure that no concurrent write can happen
262264
/// during the initial fetch, and that we won't miss any future change.
263-
private func fetchAndStartObservation(_ db: Database) throws -> Reducer.Fetched {
265+
private func fetchAndStartObservation(_ db: Database) throws -> Reducer.Fetched? {
264266
// TODO: [SR-214] remove -Opt suffix when we only support Xcode 12.5.1+
265267
let (eventsOpt, fetchOpt) = lock.synchronized {
266268
(notificationCallbacks?.events, databaseAccess?.fetch)
267269
}
268270
guard let events = eventsOpt, let fetch = fetchOpt else {
269-
// Likely a GRDB bug
270-
fatalError("can't start a cancelled or failed observation")
271+
return nil /* Cancelled */
271272
}
272273

273274
switch trackingMode {

0 commit comments

Comments
 (0)