From 12f93d5c5e239be91d09bfedddb23b1a47d7d3bc Mon Sep 17 00:00:00 2001 From: Alexander Onnikov Date: Fri, 6 Dec 2024 23:19:14 +0700 Subject: [PATCH] fix: better error handling in json migration (#7279) Signed-off-by: Alexander Onnikov --- models/core/src/migration.ts | 55 +++++++++++++++++++++++++----------- 1 file changed, 39 insertions(+), 16 deletions(-) diff --git a/models/core/src/migration.ts b/models/core/src/migration.ts index 6cae6354c7..ccebe20b86 100644 --- a/models/core/src/migration.ts +++ b/models/core/src/migration.ts @@ -352,7 +352,9 @@ async function processMigrateJsonForDoc ( if (value.startsWith('{')) { // For some reason we have documents that are already markups - const jsonId = await saveCollabJson(ctx, storageAdapter, workspaceId, collabId, value) + const jsonId = await retry(5, async () => { + return await saveCollabJson(ctx, storageAdapter, workspaceId, collabId, value) + }) update[attributeName] = jsonId continue } @@ -371,23 +373,28 @@ async function processMigrateJsonForDoc ( // If document id has changed, save it with new name to ensure we will be able to load it later const ydocId = makeCollabYdocId(collabId) if (ydocId !== currentYdocId) { - ctx.info('saving collaborative doc with new name', { collabId, ydocId, currentYdocId }) - const buffer = await storageAdapter.read(ctx, workspaceId, currentYdocId) - await storageAdapter.put( - ctx, - workspaceId, - ydocId, - Buffer.concat(buffer as any), - 'application/ydoc', - buffer.length - ) + await retry(5, async () => { + const stat = await storageAdapter.stat(ctx, workspaceId, currentYdocId) + if (stat !== undefined) { + const buffer = await storageAdapter.read(ctx, workspaceId, currentYdocId) + await storageAdapter.put( + ctx, + workspaceId, + ydocId, + Buffer.concat(buffer as any), + 'application/ydoc', + buffer.length + ) + } + }) } - - const unset = update.$unset ?? {} - update.$unset = { ...unset, [attribute.name]: 1 } - } catch (err: any) { - ctx.warn('failed to process collaborative doc', { workspaceId, collabId, currentYdocId, err: err.message }) + } catch (err) { + const error = err instanceof Error ? err.message : String(err) + ctx.warn('failed to process collaborative doc', { workspaceId, collabId, currentYdocId, error }) } + + const unset = update.$unset ?? {} + update.$unset = { ...unset, [attribute.name]: 1 } } return update @@ -510,3 +517,19 @@ export const coreOperation: MigrateOperation = { ]) } } + +async function retry (retries: number, op: () => Promise): Promise { + let error: any + while (retries > 0) { + retries-- + try { + return await op() + } catch (err: any) { + error = err + if (retries !== 0) { + await new Promise((resolve) => setTimeout(resolve, 50)) + } + } + } + throw error +}