From e6ae06798ba3591f4f9f080efba4ae928e883d82 Mon Sep 17 00:00:00 2001 From: Maarten Billemont Date: Fri, 22 May 2020 22:26:43 -0400 Subject: [PATCH] Handle store opening errors more gracefully. Store opening can fail for example when hard-locking the device while it's opening up. --- platform-darwin/Source/MPAppDelegate_Store.h | 1 + platform-darwin/Source/MPAppDelegate_Store.m | 15 +++++++++++++-- platform-darwin/Source/iOS/MPiOSAppDelegate.m | 11 ++++++----- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/platform-darwin/Source/MPAppDelegate_Store.h b/platform-darwin/Source/MPAppDelegate_Store.h index 2023738a..9abaabef 100644 --- a/platform-darwin/Source/MPAppDelegate_Store.h +++ b/platform-darwin/Source/MPAppDelegate_Store.h @@ -30,6 +30,7 @@ - (id)managedObjectContextChanged:(void ( ^ )(NSDictionary *affectedObjects))changedBlock; - (MPFixableResult)findAndFixInconsistenciesSaveInContext:(NSManagedObjectContext *)context; +- (void)retryCorruptStore; - (void)deleteAndResetStore; /** @param completion The block to execute after adding the site, executed from the main thread with the new site in the main MOC. */ diff --git a/platform-darwin/Source/MPAppDelegate_Store.m b/platform-darwin/Source/MPAppDelegate_Store.m index 53e69232..eadc2661 100644 --- a/platform-darwin/Source/MPAppDelegate_Store.m +++ b/platform-darwin/Source/MPAppDelegate_Store.m @@ -232,22 +232,27 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted ); }]; } ); - // Create a new store coordinator. NSError *error = nil; NSURL *localStoreURL = [self localStoreURL]; if (![[NSFileManager defaultManager] createDirectoryAtURL:[localStoreURL URLByDeletingLastPathComponent] withIntermediateDirectories:YES attributes:nil error:&error]) { MPError( error, @"Couldn't create our application support directory." ); + PearlRemoveNotificationObserversFrom( self.mainManagedObjectContext ); + self.mainManagedObjectContext = nil; + self.privateManagedObjectContext = nil; return; } - if (![self.storeCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[self localStoreURL] + if (![self.storeCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:localStoreURL options:@{ NSMigratePersistentStoresAutomaticallyOption: @YES, NSInferMappingModelAutomaticallyOption : @YES, STORE_OPTIONS } error:&error]) { MPError( error, @"Failed to open store." ); + PearlRemoveNotificationObserversFrom( self.mainManagedObjectContext ); + self.mainManagedObjectContext = nil; + self.privateManagedObjectContext = nil; self.storeCorrupted = @YES; [self handleCoordinatorError:error]; return; @@ -274,6 +279,12 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted ); }]; } +- (void)retryCorruptStore { + + self.storeCorrupted = @NO; + [self loadStore]; +} + - (void)deleteAndResetStore { @synchronized (self) { diff --git a/platform-darwin/Source/iOS/MPiOSAppDelegate.m b/platform-darwin/Source/iOS/MPiOSAppDelegate.m index f7acd591..a45af0f4 100644 --- a/platform-darwin/Source/iOS/MPiOSAppDelegate.m +++ b/platform-darwin/Source/iOS/MPiOSAppDelegate.m @@ -558,14 +558,15 @@ @"This may be due to corruption. You can either reset Master Password and " @"recreate your user, or E-Mail us your logs and leave your corrupt store as-is for now." preferredStyle:UIAlertControllerStyleAlert]; - [alert addAction:[UIAlertAction actionWithTitle:@"E-Mail Logs" style:UIAlertActionStyleDefault - handler:^(UIAlertAction *action) { - [self openFeedbackWithLogs:YES forVC:nil]; - }]]; + [alert addAction:[UIAlertAction actionWithTitle:@"Try Again" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { + [self retryCorruptStore]; + }]]; + [alert addAction:[UIAlertAction actionWithTitle:@"Send Logs" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { + [self openFeedbackWithLogs:YES forVC:nil]; + }]]; [alert addAction:[UIAlertAction actionWithTitle:@"Reset" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { [self deleteAndResetStore]; }]]; - [alert addAction:[UIAlertAction actionWithTitle:@"Ignore" style:UIAlertActionStyleCancel handler:nil]]; [self.window.rootViewController presentViewController:alert animated:YES completion:nil]; } ); } );