From 235047ad0bcd9b2c7dda0b23b1576cf4fc3be2d1 Mon Sep 17 00:00:00 2001 From: Girish Ramakrishnan Date: Fri, 15 May 2020 14:54:02 -0700 Subject: [PATCH] bind to source stream error event immediately download() is async and the source stream error is missed --- src/backups.js | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/src/backups.js b/src/backups.js index 66e551a5e..6c954804f 100644 --- a/src/backups.js +++ b/src/backups.js @@ -718,27 +718,31 @@ function downloadDir(backupConfig, backupFilePath, dataLayout, progressCallback, if (error) return done(new BoxError(BoxError.FS_ERROR, error.message)); async.retry({ times: 5, interval: 20000 }, function (retryCallback) { - let destStream = createWriteStream(destFilePath, backupConfig.encryption); - - destStream.on('progress', function (progress) { - const transferred = Math.round(progress.transferred/1024/1024), speed = Math.round(progress.speed/1024/1024); - if (!transferred && !speed) return progressCallback({ message: `Downloading ${entry.fullPath}` }); // 0M@0Mbps looks wrong - progressCallback({ message: `Downloading ${entry.fullPath}: ${transferred}M@${speed}Mbps` }); - }); - - // protect against multiple errors. must destroy the write stream so that a previous retry does not write - let closeAndRetry = once((error) => { - if (error) progressCallback({ message: `Download ${entry.fullPath} to ${destFilePath} errored: ${error.message}` }); - else progressCallback({ message: `Download ${entry.fullPath} to ${destFilePath} finished` }); - destStream.destroy(); - retryCallback(error); - }); - api(backupConfig.provider).download(backupConfig, entry.fullPath, function (error, sourceStream) { - if (error) return closeAndRetry(error); + if (error) { + progressCallback({ message: `Download ${entry.fullPath} to ${destFilePath} errored: ${error.message}` }); + return retryCallback(error); + } + + let destStream = createWriteStream(destFilePath, backupConfig.encryption); + + // protect against multiple errors. must destroy the write stream so that a previous retry does not write + let closeAndRetry = once((error) => { + if (error) progressCallback({ message: `Download ${entry.fullPath} to ${destFilePath} errored: ${error.message}` }); + else progressCallback({ message: `Download ${entry.fullPath} to ${destFilePath} finished` }); + sourceStream.destroy(); + destStream.destroy(); + retryCallback(error); + }); + + destStream.on('progress', function (progress) { + const transferred = Math.round(progress.transferred/1024/1024), speed = Math.round(progress.speed/1024/1024); + if (!transferred && !speed) return progressCallback({ message: `Downloading ${entry.fullPath}` }); // 0M@0Mbps looks wrong + progressCallback({ message: `Downloading ${entry.fullPath}: ${transferred}M@${speed}Mbps` }); + }); + destStream.on('error', closeAndRetry); sourceStream.on('error', closeAndRetry); - destStream.on('error', closeAndRetry); // already emits BoxError progressCallback({ message: `Downloading ${entry.fullPath} to ${destFilePath}` });