Moving to async/await on client side but get weird error

if (shift21) {
          campersInRoom.forEach(async (doc) => {
            try {
              await Meteor.callAsync('changeShift', doc.FullName, props.campLabel, shift21);
              messageApi.open({ type: 'success', content: `Room ${radio} changed` });
            } catch (error) {
              messageApi.open({ type: 'error', content: `Something went wrong. ${error}` });
            }
            // Meteor.call('changeShift', doc.FullName, props.campLabel, shift21, (err) => {
            //   if (err) {
            //     messageApi.error(err.reason);
            //   }
            // });
          });
        }

Generates client side error: “Exception while simulating the effect of invoking ‘changeShift’ Error: Called saveOriginals twice without retrieveOriginals”

Anyone familiar with this error?

Oh, perhaps this isn’t waiting for the asynchronous operation…

Maybe a for of loop.

Yeah you’ll need a for…of to process sequentially.

2 Likes

If you want to call the methods in parallel, you can fix the error by adding zodern:fix-async-stubs to your app: GitHub - zodern/fix-async-stubs: Package to remove limitations with async stubs in Meteor

It’s the same solution Meteor 3 ended up using to remove the limitations with async method calls.

3 Likes

I have an “undo/redo” mechanism for user edits that uses optimistic UI too. I am getting the same error when I do multiple undo’s/redo’s in a fast sequence:

Exception while simulating the effect of invoking 'songPage.imtdUnRedo' Error: Called saveOriginals twice without retrieveOriginals
    at LocalCollection.saveOriginals (local_collection.js:346:13)
    at Object.saveOriginals (collection.js:299:26)
    at store.<computed> [as saveOriginals] (livedata_connection.js:312:38)
    at livedata_connection.js:950:13
    at Array.forEach (<anonymous>)
    at Connection._saveOriginals (livedata_connection.js:949:33)
    at Connection.apply (livedata_connection.js:646:14)
    at Meteor.connection.apply (client.js:125:23)
    at ns.Collection._callMutatorMethod (allow-deny.js:442:27)
    at ns.Collection.update (collection.js:692:19)

The problem isn’t there when doing the same sequence slowly.

I am using zodern:fix-async-stubs, and Meteor 2.16

Any ideas?

Using zodern:fix-async-stubs should help with this, but it’s best to make sure one operation is finished before calling the next method.

It should be impossible to encounter Called saveOriginals twice without retrieveOriginals when using zodern:fix-async-stubs and Meteor’s public api’s. There might be an edge case or some scenario I didn’t account for.

The error stack trace seems to start at an odd location (it doesn’t show why collection.update is called). Is that the full stack trace? If it is, you could try setting a breakpoint where the error is shown, and the browser’s dev tools should show a longer call stack.

If you could create a reproduction, that would be very helpful.

Here 's a screenshot of the full call stack:

Unfortunately it is not easy to isolate this problem in a simple repro though.

FYI: we’re also using ‘matb33:collection-hooks’ but ‘zodern:fix-async-stubs’ is specified earlier in ‘packages’