From e6ec27a501cd41c2caabaab58b57e35ee20b04d6 Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Wed, 24 Jul 2024 19:15:52 +0100 Subject: [PATCH] Server: Prevent item size calculation task from failing when a user has been deleted --- packages/server/src/models/ItemModel.test.ts | 49 ++++++++++++++++++++ packages/server/src/models/ItemModel.ts | 14 ++++-- 2 files changed, 59 insertions(+), 4 deletions(-) diff --git a/packages/server/src/models/ItemModel.test.ts b/packages/server/src/models/ItemModel.test.ts index 03709a52ba..d9f9ab77ed 100644 --- a/packages/server/src/models/ItemModel.test.ts +++ b/packages/server/src/models/ItemModel.test.ts @@ -203,6 +203,55 @@ describe('ItemModel', () => { expect((await models().user().load(user3.id)).total_item_size).toBe(totalSize3); }); + test('should not fail when a user account has been deleted', async () => { + const { user: user1 } = await createUserAndSession(1); + const { user: user2 } = await createUserAndSession(2); + const { user: user3 } = await createUserAndSession(3); + + await createItemTree3(user1.id, '', '', [ + { + id: '000000000000000000000000000000F1', + children: [ + { + id: '00000000000000000000000000000001', + }, + ], + }, + ]); + + await createItemTree3(user2.id, '', '', [ + { + id: '000000000000000000000000000000F2', + children: [ + { + id: '00000000000000000000000000000002', + }, + { + id: '00000000000000000000000000000003', + }, + ], + }, + ]); + + await createItemTree3(user3.id, '', '', [ + { + id: '000000000000000000000000000000F3', + children: [ + { + id: '00000000000000000000000000000004', + }, + { + id: '00000000000000000000000000000005', + }, + ], + }, + ]); + + await models().user().delete(user3.id); + + await expectNotThrow(async () => models().item().updateTotalSizes()); + }); + test('should update total size when an item is deleted', async () => { const { user: user1 } = await createUserAndSession(1); diff --git a/packages/server/src/models/ItemModel.ts b/packages/server/src/models/ItemModel.ts index d767cf25e1..1bb6a83321 100644 --- a/packages/server/src/models/ItemModel.ts +++ b/packages/server/src/models/ItemModel.ts @@ -1075,6 +1075,8 @@ export default class ItemModel extends BaseModel { .concat(changes.map(c => c.user_id)), ); + const users = await this.models().user().loadByIds(userIds, { fields: ['id'] }); + const totalSizes: TotalSizeRow[] = []; for (const userId of userIds) { if (doneUserIds[userId]) continue; @@ -1089,10 +1091,14 @@ export default class ItemModel extends BaseModel { await this.withTransaction(async () => { for (const row of totalSizes) { - await this.models().user().save({ - id: row.userId, - total_item_size: row.totalSize, - }); + if (!users.find(u => u.id === row.userId)) { + modelLogger.warn(`User item refers to a user that has been deleted - skipping it: ${row.userId}`); + } else { + await this.models().user().save({ + id: row.userId, + total_item_size: row.totalSize, + }); + } } await this.models().keyValue().setValue('ItemModel::updateTotalSizes::latestProcessedChange', paginatedChanges.cursor);