woocommerce-ios
woocommerce-ios copied to clipboard
Order details: Fix crash when reloading orders
Closes WOOMOB-604
Description
Previously, there was an attempt to fix the crash when reloading the order details screen. This mitigated some of the cases but the same crash still happens sometimes after refunding a cached order and reloading the same order.
The crash is due to the use of computed variables in OrderDetailsDataSource. For the case with refunding, the app would crash in the following scenario:
- User opens the order details screen or pulls to refresh the screen.
OrderDetailsDataSourcedetermines the sections inreloadSections.- Refunds are loaded and synced in to the local storage asynchronously.
- The table view reloads data and configures the order items section, but the
aggregateOrderItemscomputed property returns an empty array due to the refund. => The app crashes when configuring order items with index out of bounds error.
The solution is to freeze all access to the results controllers upon reloadSections to avoid discrepancies when reloading data.
Testing steps
- Create an order and fulfill it.
- Open the order on the app to ensure that it's cached into local storage.
- Refund the same order on the web or on another device.
- Back to the app, pull to refresh the order details screen.
- Confirm that the app doesn't crash. The order details should display the correct details.
Since the crash happens depending on the timing of the refund syncing, so ensure to do a few tries to confirm.
Testing information
Tested and confirmed the fix on simulator iPhone 16 iOS 18.4
Screenshots
https://github.com/user-attachments/assets/0da15bb7-0b8f-46b6-87fb-03449bc8a16f
- [x] I have considered if this change warrants user-facing release notes and have added them to
RELEASE-NOTES.txtif necessary.
📲 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 Name | WooCommerce iOS Prototype | |
| Build Number | 30577 | |
| Version | PR #15764 | |
| Bundle ID | com.automattic.alpha.woocommerce | |
| Commit | 1737b8e8eac448e464f06337259fb3400bf6e1b2 | |
| Installation URL | 36dbp7fdcohp8 |
@RafaelKayumov Regarding your suggestion:
But it feels like those methods should be coupled with the reloadSections()
I think the purpose is to decouple the logic, as the calls are triggered from the higher in the hierarchy: OrderDetailsViewController > OrderDetailsViewModel > OrderDetailsDatasource > OrderDetailsResultsControllers.
The view controllers triggers table view reload when there's a change to the order object:
https://github.com/woocommerce/woocommerce-ios/blob/c8788efc3e4aa44e1786c981923218582b06cf53/WooCommerce/Classes/ViewRelated/Orders/Order%20Details/OrderDetailsViewController.swift#L204-L212
The view controller also triggers table view reload upon results controller updates:
https://github.com/woocommerce/woocommerce-ios/blob/c8788efc3e4aa44e1786c981923218582b06cf53/WooCommerce/Classes/ViewRelated/Orders/Order%20Details/OrderDetailsViewController.swift#L219-L221
Also the lookUpProductVariation(...) relies on readonly value taken from resultsControllers.productVariations which is a fetched property and can potentially vary as a result of a race condition.
Good catch! Moved product variations to a property in dc7f0dc6aba19a41a6e62f00a96e695bfed984d6.
Thanks for taking a look @jaclync.
Just checking the code changes. Is the crash reproducible before this PR? Are the repro steps different from https://github.com/woocommerce/woocommerce-ios/pull/15633 previously? If so, I wonder why it was fixed back then but not anymore.
The issue back then was 100% reproducible. The issue this PR is trying to address is more of a timing issue. The app crashes only when the refund update comes in the middle of a reload.
I responded to your other questions in the corresponding threads.