瀏覽代碼

fix(syncing-server): skip retrieval of items with invalid uuids (#683)

Karol Sójko 1 年之前
父節點
當前提交
0036d527bd

+ 1 - 0
packages/syncing-server/src/Bootstrap/Container.ts

@@ -402,6 +402,7 @@ export class ContainerConfigLoader {
           container.get(TYPES.Sync_ItemPersistenceMapper),
           container.get(TYPES.Sync_KeySystemAssociationRepository),
           container.get(TYPES.Sync_SharedVaultAssociationRepository),
+          container.get(TYPES.Sync_Logger),
         ),
       )
     container

+ 28 - 7
packages/syncing-server/src/Infra/TypeORM/TypeORMItemRepository.ts

@@ -1,6 +1,7 @@
 import { ReadStream } from 'fs'
 import { Repository, SelectQueryBuilder, Brackets } from 'typeorm'
 import { Change, MapperInterface, Uuid } from '@standardnotes/domain-core'
+import { Logger } from 'winston'
 
 import { Item } from '../../Domain/Item/Item'
 import { ItemQuery } from '../../Domain/Item/ItemQuery'
@@ -19,6 +20,7 @@ export class TypeORMItemRepository implements ItemRepositoryInterface {
     private mapper: MapperInterface<Item, TypeORMItem>,
     private keySystemAssociationRepository: KeySystemAssociationRepositoryInterface,
     private sharedVaultAssociationRepository: SharedVaultAssociationRepositoryInterface,
+    private logger: Logger,
   ) {}
 
   async save(item: Item): Promise<void> {
@@ -87,11 +89,17 @@ export class TypeORMItemRepository implements ItemRepositoryInterface {
       return null
     }
 
-    const item = this.mapper.toDomain(persistence)
+    try {
+      const item = this.mapper.toDomain(persistence)
 
-    await this.decorateItemWithAssociations(item)
+      await this.decorateItemWithAssociations(item)
 
-    return item
+      return item
+    } catch (error) {
+      this.logger.error(`Failed to find item ${uuid.value} by uuid: ${(error as Error).message}`)
+
+      return null
+    }
   }
 
   async findDatesForComputingIntegrityHash(userUuid: string): Promise<Array<{ updated_at_timestamp: number }>> {
@@ -131,17 +139,30 @@ export class TypeORMItemRepository implements ItemRepositoryInterface {
       return null
     }
 
-    const item = this.mapper.toDomain(persistence)
+    try {
+      const item = this.mapper.toDomain(persistence)
+
+      await this.decorateItemWithAssociations(item)
 
-    await this.decorateItemWithAssociations(item)
+      return item
+    } catch (error) {
+      this.logger.error(`Failed to find item ${uuid} by uuid and userUuid: ${(error as Error).message}`)
 
-    return item
+      return null
+    }
   }
 
   async findAll(query: ItemQuery): Promise<Item[]> {
     const persistence = await this.createFindAllQueryBuilder(query).getMany()
 
-    const domainItems = persistence.map((p) => this.mapper.toDomain(p))
+    const domainItems: Item[] = []
+    for (const persistencItem of persistence) {
+      try {
+        domainItems.push(this.mapper.toDomain(persistencItem))
+      } catch (error) {
+        this.logger.error(`Failed to map item ${persistencItem.uuid} to domain: ${(error as Error).message}`)
+      }
+    }
 
     await Promise.all(domainItems.map((item) => this.decorateItemWithAssociations(item)))
 

+ 7 - 1
packages/syncing-server/src/Mapping/Persistence/ItemPersistenceMapper.ts

@@ -6,6 +6,12 @@ import { TypeORMItem } from '../../Infra/TypeORM/TypeORMItem'
 
 export class ItemPersistenceMapper implements MapperInterface<Item, TypeORMItem> {
   toDomain(projection: TypeORMItem): Item {
+    const uuidOrError = Uuid.create(projection.uuid)
+    if (uuidOrError.isFailed()) {
+      throw new Error(`Failed to create item from projection: ${uuidOrError.getError()}`)
+    }
+    const uuid = uuidOrError.getValue()
+
     let duplicateOf = null
     if (projection.duplicateOf) {
       const duplicateOfOrError = Uuid.create(projection.duplicateOf)
@@ -63,7 +69,7 @@ export class ItemPersistenceMapper implements MapperInterface<Item, TypeORMItem>
         timestamps,
         updatedWithSession,
       },
-      new UniqueEntityId(projection.uuid),
+      new UniqueEntityId(uuid.value),
     )
     if (itemOrError.isFailed()) {
       throw new Error(`Failed to create item from projection: ${itemOrError.getError()}`)