KI-AGENT: Überspringe fehlende S3-Dateien beim Mandantenexport
This commit is contained in:
@@ -25,7 +25,9 @@ export type TenantFullExport = {
|
|||||||
name: string | null
|
name: string | null
|
||||||
mimeType: string | null
|
mimeType: string | null
|
||||||
size: number | null
|
size: number | null
|
||||||
contentBase64: string
|
contentBase64: string | null
|
||||||
|
missing?: boolean
|
||||||
|
error?: string
|
||||||
}[]
|
}[]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,18 +123,37 @@ const decryptEntityBankAccountsForExport = (rows: Record<string, any>[] = []) =>
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isMissingObjectError = (err: any) =>
|
||||||
|
err?.Code === "NoSuchKey" ||
|
||||||
|
err?.name === "NoSuchKey" ||
|
||||||
|
err?.$metadata?.httpStatusCode === 404
|
||||||
|
|
||||||
const loadObjectAsBase64 = async (path: string) => {
|
const loadObjectAsBase64 = async (path: string) => {
|
||||||
const { Body } = await s3.send(new GetObjectCommand({
|
try {
|
||||||
Bucket: secrets.S3_BUCKET,
|
const { Body } = await s3.send(new GetObjectCommand({
|
||||||
Key: path,
|
Bucket: secrets.S3_BUCKET,
|
||||||
}))
|
Key: path,
|
||||||
|
}))
|
||||||
|
|
||||||
const chunks: Buffer[] = []
|
const chunks: Buffer[] = []
|
||||||
for await (const chunk of Body as any) {
|
for await (const chunk of Body as any) {
|
||||||
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk))
|
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk))
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
contentBase64: Buffer.concat(chunks).toString("base64"),
|
||||||
|
missing: false,
|
||||||
|
error: null,
|
||||||
|
}
|
||||||
|
} catch (err: any) {
|
||||||
|
if (!isMissingObjectError(err)) throw err
|
||||||
|
|
||||||
|
return {
|
||||||
|
contentBase64: null,
|
||||||
|
missing: true,
|
||||||
|
error: err?.Code || err?.name || "NoSuchKey",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Buffer.concat(chunks).toString("base64")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const buildTenantFullExport = async (server: FastifyInstance, tenantId: number): Promise<TenantFullExport> => {
|
export const buildTenantFullExport = async (server: FastifyInstance, tenantId: number): Promise<TenantFullExport> => {
|
||||||
@@ -198,13 +219,25 @@ export const buildTenantFullExport = async (server: FastifyInstance, tenantId: n
|
|||||||
for (const file of fileRows) {
|
for (const file of fileRows) {
|
||||||
if (!file.path) continue
|
if (!file.path) continue
|
||||||
|
|
||||||
|
const object = await loadObjectAsBase64(file.path)
|
||||||
|
if (object.missing) {
|
||||||
|
server.log.warn({
|
||||||
|
fileId: file.id,
|
||||||
|
path: file.path,
|
||||||
|
bucket: secrets.S3_BUCKET,
|
||||||
|
error: object.error,
|
||||||
|
}, "Tenant full export skipped missing S3 object")
|
||||||
|
}
|
||||||
|
|
||||||
files.push({
|
files.push({
|
||||||
id: file.id,
|
id: file.id,
|
||||||
path: file.path,
|
path: file.path,
|
||||||
name: file.name || null,
|
name: file.name || null,
|
||||||
mimeType: file.mimeType || null,
|
mimeType: file.mimeType || null,
|
||||||
size: file.size || null,
|
size: file.size || null,
|
||||||
contentBase64: await loadObjectAsBase64(file.path),
|
contentBase64: object.contentBase64,
|
||||||
|
missing: object.missing || undefined,
|
||||||
|
error: object.error || undefined,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user