Merge pull request #29718 from overleaf/bg-history-fix-backup-errors

fix backupBlob error handling and add tests for upload failures

GitOrigin-RevId: 3abda1b70012fda20fc403593d0ee6ce04152e24
This commit is contained in:
Brian Gough
2025-11-18 10:36:45 +00:00
committed by Copybot
parent 7b331b0222
commit 3227502aeb
2 changed files with 37 additions and 1 deletions

View File

@@ -240,11 +240,13 @@ export async function backupBlob(historyId, blob, tmpPath, persistor) {
// record that we backed it up already // record that we backed it up already
await storeBlobBackup(projectId, hash) await storeBlobBackup(projectId, hash)
recordBackupConclusion('failure', 'already_backed_up') recordBackupConclusion('failure', 'already_backed_up')
// Blob already backed up so report success
return return
} }
// eventually queue this for retry - for now this will be fixed by running the script
recordBackupConclusion('failure') recordBackupConclusion('failure')
logger.warn({ error, projectId, hash }, 'Failed to upload blob to backup') logger.warn({ error, projectId, hash }, 'Failed to upload blob to backup')
// Always throw an exception if the blob is not backed up
throw error
} finally { } finally {
logger.debug({ projectId, hash }, 'Ended blob backup') logger.debug({ projectId, hash }, 'Ended blob backup')
} }

View File

@@ -152,6 +152,40 @@ describe('backupBlob', function () {
}) })
}) })
describe('when uploadBlobToBackup fails', function () {
let blob
let historyId
let mockPersistor
let uploadError
beforeEach(async function () {
blob = await makeBlobForFile(filePath)
historyId = 'abc123def456abc789def123'
uploadError = new Error('Upload failed')
// Create a mock persistor that rejects on sendStream
mockPersistor = {
sendStream: async () => {
throw uploadError
},
}
})
it('rethrows the error and does not record the blob as backed up', async function () {
await expect(
backupBlob(historyId, blob, filePath, mockPersistor)
).to.be.rejectedWith('Upload failed')
const record = await backedUpBlobs.findOne({
_id: new ObjectId(historyId),
blobs: {
$elemMatch: { $eq: new Binary(Buffer.from(blob.getHash(), 'hex')) },
},
})
expect(record).to.not.exist
})
})
const cases = [ const cases = [
{ {
name: 'text file', name: 'text file',