Move BackupsError to BoxError

This commit is contained in:
Girish Ramakrishnan
2019-10-22 20:36:20 -07:00
parent df142994a8
commit 8c9ce30d29
9 changed files with 132 additions and 145 deletions
+19 -19
View File
@@ -17,7 +17,7 @@ exports = module.exports = {
};
var assert = require('assert'),
BackupsError = require('../backups.js').BackupsError,
BoxError = require('../boxerror.js'),
debug = require('debug')('box:storage/filesystem'),
EventEmitter = require('events'),
fs = require('fs'),
@@ -35,7 +35,7 @@ function upload(apiConfig, backupFilePath, sourceStream, callback) {
assert.strictEqual(typeof callback, 'function');
mkdirp(path.dirname(backupFilePath), function (error) {
if (error) return callback(new BackupsError(BackupsError.EXTERNAL_ERROR, error.message));
if (error) return callback(new BoxError(BoxError.EXTERNAL_ERROR, error.message));
safe.fs.unlinkSync(backupFilePath); // remove any hardlink
@@ -48,15 +48,15 @@ function upload(apiConfig, backupFilePath, sourceStream, callback) {
fileStream.on('error', function (error) {
debug('[%s] upload: out stream error.', backupFilePath, error);
callback(new BackupsError(BackupsError.EXTERNAL_ERROR, error.message));
callback(new BoxError(BoxError.EXTERNAL_ERROR, error.message));
});
fileStream.on('finish', function () {
// in test, upload() may or may not be called via sudo script
const BACKUP_UID = parseInt(process.env.SUDO_UID, 10) || process.getuid();
if (!safe.fs.chownSync(backupFilePath, BACKUP_UID, BACKUP_UID)) return callback(new BackupsError(BackupsError.EXTERNAL_ERROR, 'Unable to chown:' + safe.error.message));
if (!safe.fs.chownSync(path.dirname(backupFilePath), BACKUP_UID, BACKUP_UID)) return callback(new BackupsError(BackupsError.EXTERNAL_ERROR, 'Unable to chown:' + safe.error.message));
if (!safe.fs.chownSync(backupFilePath, BACKUP_UID, BACKUP_UID)) return callback(new BoxError(BoxError.EXTERNAL_ERROR, 'Unable to chown:' + safe.error.message));
if (!safe.fs.chownSync(path.dirname(backupFilePath), BACKUP_UID, BACKUP_UID)) return callback(new BoxError(BoxError.EXTERNAL_ERROR, 'Unable to chown:' + safe.error.message));
debug('upload %s: done.', backupFilePath);
@@ -72,7 +72,7 @@ function download(apiConfig, sourceFilePath, callback) {
debug(`download: ${sourceFilePath}`);
if (!safe.fs.existsSync(sourceFilePath)) return callback(new BackupsError(BackupsError.NOT_FOUND, `File not found: ${sourceFilePath}`));
if (!safe.fs.existsSync(sourceFilePath)) return callback(new BoxError(BoxError.NOT_FOUND, `File not found: ${sourceFilePath}`));
var fileStream = fs.createReadStream(sourceFilePath);
callback(null, fileStream);
@@ -116,14 +116,14 @@ function copy(apiConfig, oldFilePath, newFilePath) {
var events = new EventEmitter();
mkdirp(path.dirname(newFilePath), function (error) {
if (error) return events.emit('done', new BackupsError(BackupsError.EXTERNAL_ERROR, error.message));
if (error) return events.emit('done', new BoxError(BoxError.EXTERNAL_ERROR, error.message));
events.emit('progress', `Copying ${oldFilePath} to ${newFilePath}`);
// this will hardlink backups saving space
var cpOptions = apiConfig.noHardlinks ? '-a' : '-al';
shell.spawn('copy', '/bin/cp', [ cpOptions, oldFilePath, newFilePath ], { }, function (error) {
if (error) return events.emit('done', new BackupsError(BackupsError.EXTERNAL_ERROR, error.message));
if (error) return events.emit('done', new BoxError(BoxError.EXTERNAL_ERROR, error.message));
events.emit('done', null);
});
@@ -141,9 +141,9 @@ function remove(apiConfig, filename, callback) {
if (!stat) return callback();
if (stat.isFile()) {
if (!safe.fs.unlinkSync(filename)) return callback(new BackupsError(BackupsError.EXTERNAL_ERROR, safe.error.message));
if (!safe.fs.unlinkSync(filename)) return callback(new BoxError(BoxError.EXTERNAL_ERROR, safe.error.message));
} else if (stat.isDirectory()) {
if (!safe.fs.rmdirSync(filename)) return callback(new BackupsError(BackupsError.EXTERNAL_ERROR, safe.error.message));
if (!safe.fs.rmdirSync(filename)) return callback(new BoxError(BoxError.EXTERNAL_ERROR, safe.error.message));
}
callback(null);
@@ -158,7 +158,7 @@ function removeDir(apiConfig, pathPrefix) {
process.nextTick(() => events.emit('progress', `Removing directory ${pathPrefix}`));
shell.spawn('removeDir', '/bin/rm', [ '-rf', pathPrefix ], { }, function (error) {
if (error) return events.emit('done', new BackupsError(BackupsError.EXTERNAL_ERROR, error.message));
if (error) return events.emit('done', new BoxError(BoxError.EXTERNAL_ERROR, error.message));
events.emit('done', null);
});
@@ -170,21 +170,21 @@ function testConfig(apiConfig, callback) {
assert.strictEqual(typeof apiConfig, 'object');
assert.strictEqual(typeof callback, 'function');
if (typeof apiConfig.backupFolder !== 'string') return callback(new BackupsError(BackupsError.BAD_FIELD, 'backupFolder must be string'));
if (typeof apiConfig.backupFolder !== 'string') return callback(new BoxError(BoxError.BAD_FIELD, 'backupFolder must be string', { field: 'backupFolder' }));
if (!apiConfig.backupFolder) return callback(new BackupsError(BackupsError.BAD_FIELD, 'backupFolder is required'));
if (!apiConfig.backupFolder) return callback(new BoxError(BoxError.BAD_FIELD, 'backupFolder is required', { field: 'backupFolder' }));
if ('noHardlinks' in apiConfig && typeof apiConfig.noHardlinks !== 'boolean') return callback(new BackupsError(BackupsError.BAD_FIELD, 'noHardlinks must be boolean'));
if ('noHardlinks' in apiConfig && typeof apiConfig.noHardlinks !== 'boolean') return callback(new BoxError(BoxError.BAD_FIELD, 'noHardlinks must be boolean', { field: 'noHardLinks' }));
if ('externalDisk' in apiConfig && typeof apiConfig.externalDisk !== 'boolean') return callback(new BackupsError(BackupsError.BAD_FIELD, 'externalDisk must be boolean'));
if ('externalDisk' in apiConfig && typeof apiConfig.externalDisk !== 'boolean') return callback(new BoxError(BoxError.BAD_FIELD, 'externalDisk must be boolean', { field: 'externalDisk' }));
fs.stat(apiConfig.backupFolder, function (error, result) {
if (error) return callback(new BackupsError(BackupsError.BAD_FIELD, 'Directory does not exist or cannot be accessed: ' + error.message));
if (!result.isDirectory()) return callback(new BackupsError(BackupsError.BAD_FIELD, 'Backup location is not a directory'));
if (error) return callback(new BoxError(BoxError.BAD_FIELD, 'Directory does not exist or cannot be accessed: ' + error.message), { field: 'backupFolder' });
if (!result.isDirectory()) return callback(new BoxError(BoxError.BAD_FIELD, 'Backup location is not a directory', { field: 'backupFolder' }));
mkdirp(path.join(apiConfig.backupFolder, 'snapshot'), function (error) {
if (error && error.code === 'EACCES') return callback(new BackupsError(BackupsError.BAD_FIELD, `Access denied. Run "chown yellowtent:yellowtent ${apiConfig.backupFolder}" on the server`));
if (error) return callback(new BackupsError(BackupsError.BAD_FIELD, error.message));
if (error && error.code === 'EACCES') return callback(new BoxError(BoxError.BAD_FIELD, `Access denied. Run "chown yellowtent:yellowtent ${apiConfig.backupFolder}" on the server`, { field: 'backupFolder' }));
if (error) return callback(new BoxError(BoxError.BAD_FIELD, error.message, { field: 'backupFolder' }));
callback(null);
});
+15 -15
View File
@@ -22,7 +22,7 @@ exports = module.exports = {
var assert = require('assert'),
async = require('async'),
backups = require('../backups.js'),
BackupsError = require('../backups.js').BackupsError,
BoxError = require('../boxerror.js'),
debug = require('debug')('box:storage/gcs'),
EventEmitter = require('events'),
GCS = require('@google-cloud/storage').Storage,
@@ -68,7 +68,7 @@ function upload(apiConfig, backupFilePath, sourceStream, callback) {
function done(error) {
if (error) {
debug('[%s] upload: gcp upload error.', backupFilePath, error);
return callback(new BackupsError(BackupsError.EXTERNAL_ERROR, `Error uploading ${backupFilePath}. Message: ${error.message} HTTP Code: ${error.code}`));
return callback(new BoxError(BoxError.EXTERNAL_ERROR, `Error uploading ${backupFilePath}. Message: ${error.message} HTTP Code: ${error.code}`));
}
callback(null);
@@ -95,10 +95,10 @@ function download(apiConfig, backupFilePath, callback) {
var readStream = file.createReadStream()
.on('error', function(error) {
if (error && error.code == 404){
ps.emit('error', new BackupsError(BackupsError.NOT_FOUND));
ps.emit('error', new BoxError(BoxError.NOT_FOUND));
} else {
debug('[%s] download: gcp stream error.', backupFilePath, error);
ps.emit('error', new BackupsError(BackupsError.EXTERNAL_ERROR, error));
ps.emit('error', new BoxError(BoxError.EXTERNAL_ERROR, error));
}
})
;
@@ -151,8 +151,8 @@ function copy(apiConfig, oldFilePath, newFilePath) {
getBucket(apiConfig).file(entry.fullPath).copy(path.join(newFilePath, relativePath), function(error) {
if (error) debug('copyBackup: gcs copy error', error);
if (error && error.code === 404) return iteratorCallback(new BackupsError(BackupsError.NOT_FOUND, 'Old backup not found'));
if (error) return iteratorCallback(new BackupsError(BackupsError.EXTERNAL_ERROR, error.message));
if (error && error.code === 404) return iteratorCallback(new BoxError(BoxError.NOT_FOUND, 'Old backup not found'));
if (error) return iteratorCallback(new BoxError(BoxError.EXTERNAL_ERROR, error.message));
iteratorCallback(null);
});
@@ -219,13 +219,13 @@ function testConfig(apiConfig, callback) {
assert.strictEqual(typeof apiConfig, 'object');
assert.strictEqual(typeof callback, 'function');
if (typeof apiConfig.projectId !== 'string') return callback(new BackupsError(BackupsError.BAD_FIELD, 'projectId must be a string'));
if (!apiConfig.credentials || typeof apiConfig.credentials !== 'object') return callback(new BackupsError(BackupsError.BAD_FIELD, 'credentials must be an object'));
if (typeof apiConfig.credentials.client_email !== 'string') return callback(new BackupsError(BackupsError.BAD_FIELD, 'credentials.client_email must be a string'));
if (typeof apiConfig.credentials.private_key !== 'string') return callback(new BackupsError(BackupsError.BAD_FIELD, 'credentials.private_key must be a string'));
if (typeof apiConfig.projectId !== 'string') return callback(new BoxError(BoxError.BAD_FIELD, 'projectId must be a string'));
if (!apiConfig.credentials || typeof apiConfig.credentials !== 'object') return callback(new BoxError(BoxError.BAD_FIELD, 'credentials must be an object'));
if (typeof apiConfig.credentials.client_email !== 'string') return callback(new BoxError(BoxError.BAD_FIELD, 'credentials.client_email must be a string'));
if (typeof apiConfig.credentials.private_key !== 'string') return callback(new BoxError(BoxError.BAD_FIELD, 'credentials.private_key must be a string'));
if (typeof apiConfig.bucket !== 'string') return callback(new BackupsError(BackupsError.BAD_FIELD, 'bucket must be a string'));
if (typeof apiConfig.prefix !== 'string') return callback(new BackupsError(BackupsError.BAD_FIELD, 'prefix must be a string'));
if (typeof apiConfig.bucket !== 'string') return callback(new BoxError(BoxError.BAD_FIELD, 'bucket must be a string'));
if (typeof apiConfig.prefix !== 'string') return callback(new BoxError(BoxError.BAD_FIELD, 'prefix must be a string'));
// attempt to upload and delete a file with new credentials
var bucket = getBucket(apiConfig);
@@ -239,16 +239,16 @@ function testConfig(apiConfig, callback) {
uploadStream.on('error', function(error) {
debug('testConfig: failed uploading cloudron-testfile', error);
if (error && error.code && (error.code == 403 || error.code == 404)) {
return callback(new BackupsError(BackupsError.BAD_FIELD, error.message));
return callback(new BoxError(BoxError.BAD_FIELD, error.message));
}
return callback(new BackupsError(BackupsError.EXTERNAL_ERROR, error.message));
return callback(new BoxError(BoxError.EXTERNAL_ERROR, error.message));
});
uploadStream.on('finish', function() {
debug('testConfig: uploaded cloudron-testfile ' + JSON.stringify(arguments));
bucket.file(path.join(apiConfig.prefix, 'cloudron-testfile')).delete(function(error) {
if (error) return callback(new BackupsError(BackupsError.EXTERNAL_ERROR, error.message));
if (error) return callback(new BoxError(BoxError.EXTERNAL_ERROR, error.message));
debug('testConfig: deleted cloudron-testfile');
callback();
});
+14 -14
View File
@@ -23,7 +23,7 @@ var assert = require('assert'),
async = require('async'),
AWS = require('aws-sdk'),
backups = require('../backups.js'),
BackupsError = require('../backups.js').BackupsError,
BoxError = require('../boxerror.js'),
chunk = require('lodash.chunk'),
debug = require('debug')('box:storage/s3'),
EventEmitter = require('events'),
@@ -101,7 +101,7 @@ function upload(apiConfig, backupFilePath, sourceStream, callback) {
s3.upload(params, { partSize, queueSize: 1 }, function (error, data) {
if (error) {
debug('Error uploading [%s]: s3 upload error.', backupFilePath, error);
return callback(new BackupsError(BackupsError.EXTERNAL_ERROR, `Error uploading ${backupFilePath}. Message: ${error.message} HTTP Code: ${error.code}`));
return callback(new BoxError(BoxError.EXTERNAL_ERROR, `Error uploading ${backupFilePath}. Message: ${error.message} HTTP Code: ${error.code}`));
}
debug(`Uploaded ${backupFilePath}: ${JSON.stringify(data)}`);
@@ -131,10 +131,10 @@ function download(apiConfig, backupFilePath, callback) {
multipartDownload.on('error', function (error) {
if (S3_NOT_FOUND(error)) {
ps.emit('error', new BackupsError(BackupsError.NOT_FOUND, `Backup not found: ${backupFilePath}`));
ps.emit('error', new BoxError(BoxError.NOT_FOUND, `Backup not found: ${backupFilePath}`));
} else {
debug(`download: ${apiConfig.bucket}:${backupFilePath} s3 stream error.`, error);
ps.emit('error', new BackupsError(BackupsError.EXTERNAL_ERROR, error.message || error.code)); // DO sets 'code'
ps.emit('error', new BoxError(BoxError.EXTERNAL_ERROR, error.message || error.code)); // DO sets 'code'
}
});
@@ -219,8 +219,8 @@ function copy(apiConfig, oldFilePath, newFilePath) {
function done(error) {
if (error) debug(`copy: s3 copy error when copying ${entry.fullPath}: ${error}`);
if (error && S3_NOT_FOUND(error)) return iteratorCallback(new BackupsError(BackupsError.NOT_FOUND, `Old backup not found: ${entry.fullPath}`));
if (error) return iteratorCallback(new BackupsError(BackupsError.EXTERNAL_ERROR, `Error copying ${entry.fullPath} : ${error.code} ${error}`));
if (error && S3_NOT_FOUND(error)) return iteratorCallback(new BoxError(BoxError.NOT_FOUND, `Old backup not found: ${entry.fullPath}`));
if (error) return iteratorCallback(new BoxError(BoxError.EXTERNAL_ERROR, `Error copying ${entry.fullPath} : ${error.code} ${error}`));
iteratorCallback(null);
}
@@ -405,13 +405,13 @@ function testConfig(apiConfig, callback) {
assert.strictEqual(typeof apiConfig, 'object');
assert.strictEqual(typeof callback, 'function');
if (typeof apiConfig.accessKeyId !== 'string') return callback(new BackupsError(BackupsError.BAD_FIELD, 'accessKeyId must be a string'));
if (typeof apiConfig.secretAccessKey !== 'string') return callback(new BackupsError(BackupsError.BAD_FIELD, 'secretAccessKey must be a string'));
if (typeof apiConfig.accessKeyId !== 'string') return callback(new BoxError(BoxError.BAD_FIELD, 'accessKeyId must be a string', { field: 'accessKeyId' }));
if (typeof apiConfig.secretAccessKey !== 'string') return callback(new BoxError(BoxError.BAD_FIELD, 'secretAccessKey must be a string', { field: 'secretAccessKey' }));
if (typeof apiConfig.bucket !== 'string') return callback(new BackupsError(BackupsError.BAD_FIELD, 'bucket must be a string'));
if (typeof apiConfig.prefix !== 'string') return callback(new BackupsError(BackupsError.BAD_FIELD, 'prefix must be a string'));
if ('signatureVersion' in apiConfig && typeof apiConfig.signatureVersion !== 'string') return callback(new BackupsError(BackupsError.BAD_FIELD, 'signatureVersion must be a string'));
if ('endpoint' in apiConfig && typeof apiConfig.endpoint !== 'string') return callback(new BackupsError(BackupsError.BAD_FIELD, 'endpoint must be a string'));
if (typeof apiConfig.bucket !== 'string') return callback(new BoxError(BoxError.BAD_FIELD, 'bucket must be a string', { field: 'bucket' }));
if (typeof apiConfig.prefix !== 'string') return callback(new BoxError(BoxError.BAD_FIELD, 'prefix must be a string', { field: 'prefix' }));
if ('signatureVersion' in apiConfig && typeof apiConfig.signatureVersion !== 'string') return callback(new BoxError(BoxError.BAD_FIELD, 'signatureVersion must be a string', { field: 'signatureVersion' }));
if ('endpoint' in apiConfig && typeof apiConfig.endpoint !== 'string') return callback(new BoxError(BoxError.BAD_FIELD, 'endpoint must be a string', { field: 'endpoint' }));
// attempt to upload and delete a file with new credentials
getS3Config(apiConfig, function (error, credentials) {
@@ -425,7 +425,7 @@ function testConfig(apiConfig, callback) {
var s3 = new AWS.S3(credentials);
s3.putObject(params, function (error) {
if (error) return callback(new BackupsError(BackupsError.EXTERNAL_ERROR, error.message || error.code)); // DO sets 'code'
if (error) return callback(new BoxError(BoxError.EXTERNAL_ERROR, error.message || error.code)); // DO sets 'code'
var params = {
Bucket: apiConfig.bucket,
@@ -433,7 +433,7 @@ function testConfig(apiConfig, callback) {
};
s3.deleteObject(params, function (error) {
if (error) return callback(new BackupsError(BackupsError.EXTERNAL_ERROR, error.message || error.code)); // DO sets 'code'
if (error) return callback(new BoxError(BoxError.EXTERNAL_ERROR, error.message || error.code)); // DO sets 'code'
callback();
});