WatermelonDB: Sync error handling
Are there any good examples of error handling for sync in both the frontend and backend that I can reference? I’m having trouble with the pullChanges & pushChanges changing records to synced even though some records failed to be pushed or pulled.
EDIT: I added try catch to throw 503 error if any error occurs and it works but something about it feels off
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 19 (10 by maintainers)
@Skullcan I managed to fix it! Hopefully it stays that way 🤣
Here’s how I fixed it in case anyone else needs help with it:
0.0I’m not sure why it only does it for some records and not others but my timestamps were being sent back as strings so I had to parse all my timestamps to integers in the knex setup. This comment on the knex forums is what ultimately helped me: https://github.com/knex/knex/issues/3071#issuecomment-509429039[Diagnostic error: [Sync] Server wants client to create record table_name#id1234567890123, but it already exists locally. This may suggest last sync partially executed, and then failed; or it could be a serious bug. Will update existing record instead.]Upon creation & update of the record on the server, I set the timestamps to the timestamps of the local database record instead of letting postgres automatically update the timestamps....Will delete local record and recreate it insteadI had to separate the creation and update sync from the deletion sync because of the foreign key constraints. The order of the former and latter had to be reversed. I couldn’t use cascade deletions because I needed to add my deleted records to my deleted records tableI’m glad I could help!
sendCreatedAsUpdatedworked like a charm, thanks so much for all the help you’ve been a lifesaver!When I had this problem I solved using the SyncId method as I mentioned before, but then again, my project was expected to not be big and the extra overhead was not a problem.
Maybe you could try using the ‘sendCreatedAsUpdated’ flag and see if it helps. There’s a discussion about something similar to your problem here #649
@Skullcan Ok I’ll test that out next week and let you know if it works, thanks so much for all the help!
Your timestamp fields in postgres can be stored the way you are doing, but the watermelon sync function expect the Unix Timestamp in the
changes.You will have to convert the Human readable timestamp from postgre to Unix timestamp before returning they to the
changes. So your"2021-12-23T15:16:10.388Z"have to be changed to1640278863Here is a snippet of the tail end of my
changesobjectThis might be the reason you are having problems with the sync altogether tbh.
No, they are not different. I meant I always trust the values in the control fields created_at, updated_at and deleted_at in my database. And you are right in your approach, you have to return the Date.now() in your sync backend as your last.
Oh I see, I had this problem in another project… only managed to work around it by creating a sync_id… and in my pullChanges I only return the changes with Ids that are not the current syncId from the ones I sent from the same client. Something like this…
This way, even if the created/updated at have a newer timestamp, the syncId prevent the attempt to create a record that was created by the same client. But then again, my need may be different than yours, so I don’t know if this approach works for you.
The triggered withChangeForTables from the remote server always have the ‘synced’ status. So I filter then and only call sync when I have at least 1 record that needs to be pushed. Debug it and check if this is your case too.
I see you did the basically the same thing in your .pipe() function… well… I tried doing this way… Didn’t work for me… so I did something like the code above. And now it’s working fine. The withChangesForTables only start a new sync if I change something locally.
It is probably the case, yes.
Please take into consideration that the codes are just a mockup and not optimized. I wouldn’t use them in production.