Skip to content

Conversation

@itsmeichigo
Copy link
Contributor

@itsmeichigo itsmeichigo commented Apr 24, 2025

Closes WOOMOB-316

Description

In #14961 I added a workaround to drop the database and force crash the app to help users recover from their corrupted database. This caused an unexpected crash on the Blaze dashboard upon resetting the database, causing the app crash earlier without details about the saving failure.

This PR attempts to prevent this by:

  • Triggering a different notification that is listented to only by the SessionManager to clear the timestamps for cached data.
    - Adding a future-proof update to prevent crash on the Blaze dashboard when the database is reset.

Steps to reproduce

Smoke test the app with a store that's eligible for Blaze and confirm that the Blaze dashboard is still loaded without issues.

Testing information

  • Smoke tested the Blaze dashboard card using simulator iPhone 16 Pro iOS 18.2.
  • Added a unit test to confirm the reset of timestamps upon dropping database.

Screenshots

N/A


  • I have considered if this change warrants user-facing release notes and have added them to RELEASE-NOTES.txt if necessary.

Reviewer (or Author, in the case of optional code reviews):

Please make sure these conditions are met before approving the PR, or request changes if the PR needs improvement:

  • The PR is small and has a clear, single focus, or a valid explanation is provided in the description. If needed, please request to split it into smaller PRs.
  • Ensure Adequate Unit Test Coverage: The changes are reasonably covered by unit tests or an explanation is provided in the PR description.
  • Manual Testing: The author listed all the tests they ran, including smoke tests when needed (e.g., for refactorings). The reviewer confirmed that the PR works as expected on all devices (phone/tablet) and no regressions are added.

@itsmeichigo itsmeichigo added type: crash The worst kind of bug. feature: Blaze Related to the integration of the Blaze ads platform feature: core Core work. See "category: tooling" and "category: architecture" labels Apr 24, 2025
@itsmeichigo itsmeichigo added this to the 22.3 milestone Apr 24, 2025
@wpmobilebot
Copy link
Collaborator

wpmobilebot commented Apr 24, 2025

App Icon📲 You can test the changes from this Pull Request in WooCommerce iOS Prototype by scanning the QR code below to install the corresponding build.

App NameWooCommerce iOS Prototype
Build Number29510
VersionPR #15546
Bundle IDcom.automattic.alpha.woocommerce
Commita8bd777
Installation URL63iad8mvfq240
Automatticians: You can use our internal self-serve MC tool to give yourself access to those builds if needed.

Copy link
Contributor

@jaclync jaclync left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the change is to post a new notification that only one class subscribes, I think the changes are pretty confined and we can just smoke test the app to ensure the Blaze dashboard card works as before without crashes. Left some comments.

do {
try persistentContainer.persistentStoreCoordinator.destroyPersistentStore(at: storeURL, type: .sqlite, options: nil)
NotificationCenter.default.post(name: .StorageManagerDidResetStorage, object: self)
NotificationCenter.default.post(name: .StorageManagerDidInvalidateCachedData, object: self)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: what's the part that invalidates cached data? maybe it could more specific to what this function does like StorageManagerDidDropDatabase/StorageManagerDidDropStorage?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in e7ce752.

Comment on lines -188 to -189
// Listens when the core data stack is rest.
NotificationCenter.default.addObserver(self, selector: #selector(handleStorageDidReset), name: .StorageManagerDidResetStorage, object: nil)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❓ Maybe this observation of StorageManagerDidResetStorage can still be kept, since this notification is still posted after destroying the database in createPersistentContainer's recovery upon error. Or do we also want to replace StorageManagerDidResetStorage with the new notification there for consistency? I'm not sure if StorageManagerDidResetStorage notification has always been posted in createPersistentContainer from git as there was some refactoring on the file.

try container.persistentStoreCoordinator.destroyPersistentStore(at: storeURL,
ofType: storeDescription.type,
options: nil)
NotificationCenter.default.post(name: .StorageManagerDidResetStorage, object: self)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point! This has been restored in 7109840.

Comment on lines 326 to 331
refetchAllResultsControllers()
}

/// Refetching all the results controllers is necessary after a storage reset in `onDidResetContent`
/// callback and before reloading UI that involves more than one results controller.
func refetchAllResultsControllers() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💬 How about trying the new notification fix first, to isolate the issue? If the crash still happens with a different stack trace, we know it's a different issue and can consider adding the changes to refetch both results controllers.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good! I revert the change in 361f079.

@itsmeichigo itsmeichigo marked this pull request as ready for review April 25, 2025 11:01
@itsmeichigo
Copy link
Contributor Author

Thanks @jaclync for the reviews! I addressed the suggestions in the subsequent commits. This PR is ready for another look.

@itsmeichigo itsmeichigo requested a review from jaclync April 25, 2025 11:02
Copy link
Contributor

@jaclync jaclync left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thanks for making these changes and we can observe the crash after the release.

Comment on lines 291 to 298
@objc func handleStorageDidReset() {
@objc func handleStorageDidInvalidateData() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: how about marking resetTimestampsValues as @objc, removing this function, and calling resetTimestampsValues from the two notifications instead? I wasn't very sure the "invalidate data" part in the function name.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea! Done in 56c7182.

}
}

func test_core_data_database_drop_clears_timestamps_stores() throws {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for adding this test case!

@itsmeichigo itsmeichigo enabled auto-merge April 28, 2025 04:08
@itsmeichigo itsmeichigo merged commit 9a04272 into trunk Apr 28, 2025
13 checks passed
@itsmeichigo itsmeichigo deleted the fix/woomob-316-prevent-crash-resetting-database branch April 28, 2025 04:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature: Blaze Related to the integration of the Blaze ads platform feature: core Core work. See "category: tooling" and "category: architecture" type: crash The worst kind of bug.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants