Not sure to describe the issue but we are trying to upgrade to mongoDB 5.0 and have updated mongoose to 6.0.12 in the process of upgrading mongoDB. In running the batch tests (jest), we are stuck on the error message "Final argument to executeLegacyOperation
must be a callback"
The entire message is :
Failed: Array [
GraphQLError {
"locations": Array [
[Object],
],
"message": "Final argument to `executeLegacyOperation` must be a callback",
"path": Array [
"upsertBatchRole",
],
},
]
An example of a test that is failing:
test('should update existing items and return UPDATED status', async () => {
const {
data: { upsertBatchRole },
} = await gqlClient.fetch<{ upsertBatchRole: GQLUpsertBatchRoleOutput }>(upsertBatchRoleMutation, {
condition: {},
input: [
{
name: 'new',
id: '57',
},
],
});
expect(upsertBatchRole).not.toBeNull();
const { status, data } = upsertBatchRole as GQLUpsertBatchRoleOutput;
const unitedData = uniteCategorizedArrays<GQLRole>({ ...data });
expect(status).toBe(ms.UPDATED);
expect(unitedData.length).toBe(1);
expect(unitedData[0]).toHaveProperty('name');
expect(unitedData[0]?.name).toBe('new');
_.forEach(unitedData, (item) => {
expect(item).toHaveProperty('id');
expect(item).toHaveProperty('name');
});
const {
data: { roleList },
} = await gqlClient.fetch(`
roleList {
name
}
`);
const orderedList = _.sortBy(roleList, 'name');
expect(orderedList).toHaveLength(1);
expect(orderedList[0].name).toBe('new');
});
Currently, graphql is at 15.5.1. Tried to upgrade graphql and got as far as 15.8.0 as higher versions produced a different error. Current node version is 14.21.3
Not sure if graphql is the issue here so looking for any ideas on how to resolve the above issue.
UPDATED
Here is a code snippet from upsertBatchEntity.js:
async function updateBatchEntity(Collection, entitiesToUpdate, gqlInfo) {
if (_.isEmpty(entitiesToUpdate)) return { status: ms.UPDATED, data: [] };
const transactionSession = getCurrentTransactionSessionFromGQLInfo(gqlInfo);
const bulkUpdate = Collection.collection.initializeOrderedBulkOp({
session: transactionSession,
});
_.forEach(entitiesToUpdate, (entity) => {
const _id = new mongoose.Types.ObjectId(entity._id);
const entityProperties = _.omit(entity, ['id', '_id']);
const convertedEntityProperties = convertEntityPropertiesToObjectIdWhereNeeded(Collection, entityProperties);
bulkUpdate.find({ _id }).updateOne({ $set: { ...convertedEntityProperties, updatedAt: new Date() } });
});
await bulkUpdate.execute(null, { session: transactionSession });
clearEntityLoadersCache(Collection.modelName, gqlInfo);
return {
status: ms.UPDATED,
data: entitiesToUpdate,
};
}
It looks like updateOne()
is async and expects a callback - documentation
Where you are doing:
bulkUpdate.find({ _id }).updateOne({ $set: { ...convertedEntityProperties, updatedAt: new Date() } });
You'll need to provide a callback or possibly just await
it.