Open alex-breen opened 1 year ago
Hi @alex-breen 👋 thanks for raising this issue. This sounds like behavior I've seen with optimistic concurrency before where the server rejects the mutation because the record version hadn't updated between consecutive DataStore.save
calls.
But, this issue does sound a bit different due to the null
values replacing unchanged fields. Thank you for the reproduction steps, I will try to reproduce this issue and report back.
Hi @chrisbonifacio and @stocaaro - with release aws-amplify@6.0.12 and PR https://github.com/aws-amplify/amplify-js/pull/12813 has this issue been fixed or mitigated?
Hi @alex-breen,
The PR I closed above solved the problem, but introduced issues that could break expectations regarding how custom conflict resolution is handled. At this time we don't have a fix for this problem that wouldn't break something else.
While the problem persists, you can use custom conflict resolution to fix this behavior in your app.
Thanks, Aaron
Before opening, please confirm:
JavaScript Framework
React
Amplify APIs
Authentication, GraphQL API, DataStore, Storage
Amplify Categories
auth, storage, function, api, hosting
Environment information
Describe the bug
If DataStore's conflict resolution is set to "Optimistic Concurrency" and an update mutation fails due to a "ConflictUnhandled" error, the Amplify client automatically retries but passes null values for all unchanged fields.
Cases in which "ConflictUnhandled" error is thrown includes a) one client makes a change offline, then comes back online b) two DataStore saves to the same record in 300 ms.
The key problem is that the unchanged fields turn to null. Just failing the mutation would be less destructive.
Expected behavior
Mutation (the retry) is successful or fails cleanly (ideally with an error event Hub can pick up). without destroying data.
Reproduction steps
Run two separate javascript clients with DataStore. Switch one to be "offline". Update the same record on both the online and offline clients. Return the offline client to be online.
Or...on the same client, update the same record twice, with 300 ms time gap between.
Code Snippet
Pretty typical stuff...
Log output
aws-exports.js
No response
Manual configuration
No response
Additional configuration
No response
Mobile Device
No response
Mobile Operating System
No response
Mobile Browser
No response
Mobile Browser Version
No response
Additional information and screenshots
As a workaround, I've returned to using "Automerge". While better (because the data does not get destroyed with null values), updates do fail, but fail silently. E.g. - DataStore will return success, but the graphQL mutation will return the newer value (based on _version field), without any error (on Hub or elsewhere) that the data was not saved. This is less problematic for an offline/online scenario as the user might understand that they made the change while offline (even if done after the change they made online). But for the case that two saves are made within 300ms of the other, the user just sees that the second change fails unexpectedly and immediately.