diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index a0e0b4099..b9de79933 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -4495,9 +4495,9 @@ "optional": true }, "safetydance": { - "version": "0.4.0", - "from": "safetydance@0.4.0", - "resolved": "https://registry.npmjs.org/safetydance/-/safetydance-0.4.0.tgz" + "version": "0.6.0", + "from": "safetydance@0.6.0", + "resolved": "https://registry.npmjs.org/safetydance/-/safetydance-0.6.0.tgz" }, "sass-graph": { "version": "2.2.4", diff --git a/package.json b/package.json index 2ef749baf..fc6fc3cc9 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "progress-stream": "^2.0.0", "proxy-middleware": "^0.13.0", "s3-block-read-stream": "^0.2.0", - "safetydance": "^0.4.0", + "safetydance": "^0.6.0", "semver": "^4.3.6", "showdown": "^1.6.0", "split": "^1.0.0", diff --git a/src/backups.js b/src/backups.js index 2a1a2d28d..07e3e6789 100644 --- a/src/backups.js +++ b/src/backups.js @@ -225,7 +225,11 @@ function sync(backupConfig, backupId, dataDir, callback) { } else if (task.operation === 'remove') { api(backupConfig.provider).remove(backupConfig, getBackupFilePath(backupConfig, backupId, task.path), iteratorCallback); } - }, callback); + }, function (error) { + if (error) return callback(new BackupsError(BackupsError.EXTERNAL_ERROR, error.message)); + + callback(); + }); } function saveEmptyDirs(appDataDir, callback) { diff --git a/src/syncer.js b/src/syncer.js index 359defd3b..9ab306db5 100644 --- a/src/syncer.js +++ b/src/syncer.js @@ -1,7 +1,7 @@ 'use strict'; var assert = require('assert'), - fs = require('fs'), + debug = require('debug')('box:syncer'), path = require('path'), paths = require('./paths.js'), safe = require('safetydance'); @@ -15,7 +15,7 @@ function readCache(cacheFile) { var cache = safe.fs.readFileSync(cacheFile, 'utf8'); if (!cache) return [ ]; - var result = cache.split('\n').map(JSON.parse); + var result = cache.trim().split('\n').map(JSON.parse); return result; } @@ -25,8 +25,7 @@ function readTree(dir) { var list = safe.fs.readdirSync(dir).sort(); if (!list) return [ ]; - // TODO: handle lstat errors - return list.map(function (e) { return { stat: fs.lstatSync(path.join(dir, e)), name: e }; }); + return list.map(function (e) { return { stat: safe.fs.lstatSync(path.join(dir, e)), name: e }; }); } // TODO: concurrency @@ -42,7 +41,8 @@ function sync(dir, taskProcessor, callback) { var cache = readCache(cacheFile); - var newCacheFd = fs.openSync(newCacheFile, 'w'); // truncates any existing file + var newCacheFd = safe.fs.openSync(newCacheFile, 'w'); // truncates any existing file + if (newCacheFd === -1) return callback(new Error('Error opening new cache file: ' + safe.error.message)); var dummyCallback = function() { }; @@ -59,6 +59,7 @@ function sync(dir, taskProcessor, callback) { var entryPath = path.join(relpath, entries[i].name); var stat = entries[i].stat; + if (!stat) continue; // some stat error if (!stat.isDirectory() && !stat.isFile()) continue; if (stat.isSymbolicLink()) continue; @@ -67,7 +68,7 @@ function sync(dir, taskProcessor, callback) { continue; } - fs.appendFileSync(newCacheFd, JSON.stringify({ path: entryPath, mtime: stat.mtime.getTime() }) + '\n'); + safe.fs.appendFileSync(newCacheFd, JSON.stringify({ path: entryPath, mtime: stat.mtime.getTime() }) + '\n'); advanceCache(entryPath); @@ -83,12 +84,13 @@ function sync(dir, taskProcessor, callback) { } traverse(''); - advanceCache(''); // remove rest of the cache entries + advanceCache(''); // remove rest of the cache entries // move the new cache file - fs.closeSync(newCacheFd); - fs.unlinkSync(cacheFile); - fs.renameSync(cacheFile, newCacheFd); + safe.fs.closeSync(newCacheFd); + safe.fs.unlinkSync(cacheFile); + + if (!safe.fs.renameSync(newCacheFile, cacheFile)) debug('Unable to save new cache file'); callback(); } \ No newline at end of file