Fix KeyNotFoundException and NullReferenceException when catalog items are deleted #940
+18
−2
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
When catalog items are deleted, basket items and orders retain references to non-existent product IDs, causing the WebApp to crash with
KeyNotFoundExceptionduring basket operations and the Catalog API to crash withNullReferenceExceptionduring order validation.Changes
BasketState.cs
TryGetValue()to handle missing catalog itemsOrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs
Example
Before:
After:
This defensive approach allows the system to continue functioning when data inconsistencies occur across microservices, avoiding the need for distributed transaction coordination.
Original prompt
This section details on the original issue you should resolve
<issue_title>Referential integrity bugs related to catalog, basket, and order</issue_title>
<issue_description>Hi,
There appears to be code logic that breaks referential integrity constraints and causes inconsistencies during execution. I would like to share this to understand if the issues are valid in the context of the application, and whether these bugs could be addressed. Thank you in advance.
The issues are related to the data associations established across the catalog, basket, and order microservices, where the baskets and orders contain item IDs that reference the item IDs of the corresponding products in the catalog.
Below are the steps to reproduce the bugs and their potential impact on the system.
Scenario 1: Catalog-Basket
Steps to reproduce bugs:
Consider a client that manages its cart items via the Web App and an administrator who manages the catalog via the REST API.
The flow of requests is illustrated in a shared figure. The illustrated databases contain data from the original application. For simplicity, only the catalog and basket services are represented, along with the most relevant calls and arguments.
Description of the bugs:
1. Absence of cascading delete: each basket item contains the ID of the corresponding catalog item, resembling a foreign key. However, when the catalog item is deleted (fig. call 7), this action is not propagated to the basket, leaving a reference that is no longer valid.
During checkout (or even when viewing the cart), the web app's
FetchBasketItemsAsyncreceives data from querying the basket (fig. calls 9-10, where the returned item IDs contain the deleted item ID) that is inconsistent with the data obtained from querying the catalog (fig. calls 11-12, where the returned items do not contain the deleted item).The web app's
FetchBasketItemsAsyncexpects that every basket item is present in the returned catalog items, and during iteration, akey not founderror occurs, causing the web app to crash and remain unavailable.2. Concurrent operations: even if cascading effects are implemented, bugs may still occur if the admin deletes the item from the catalog concurrently with the client adding the item to the basket.
In particular, if the deletion in the catalog (fig. call 7) occurs after the client obtains the item ID to add the item to the basket (which requires reading the catalog prior to fig. call 1), and before the write to the basket database to add the item (fig. call 3), the cascading effects would take action on the basket database before the association would be successfuly established, and the (invalid) reference would still be created upon the write operation (fig. call 3).
Scenario 2: Catalog-Basket-Order
Steps to reproduce bugs:
Consider a client that manages its cart items via the Web App and an administrator who manages the catalog via the REST API.
The flow of requests is illustrated in a shared figure. For simplicity, we omit the two initial steps below from the figure, as they are identical to those in the previous scenario.
submittedtoawaiting validation, and proceeds to check if the stock is available. (fig. calls 6-9)Description of the bugs:
1. Absence of cascading delete: each order item contains the ID of the corresponding catalog item, resembling a foreign key. However, when the catalog item is deleted (fig. call 5), this action is not propagated to the order, leaving a reference that is no longer valid.
When checking the available stock, the catalog event handler receives data (fig. call 7, where the order items parameter contains the deleted item) that is inconsistent with the data obtained from querying the ...
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.