This code checks user permissions for uploading file, and if user can upload, then the file undergoes a check to see if it exists in SharePoint. If so then the file is pulled and uploaded to S3 bucket. This all works fine, but I have been told all these catches create callback hell. I've been trying to implement promises but I am very confused on how to change these callbacks to promises. Appreciate any help.
//////////////////
// Dependencies //
//////////////////
const path = require('path');
const fs = require('fs');
const ping = require('tcp-ping');
const Semaphore = require('mysql-semaphore');
const dateFormat = require('dateformat');
const randomstring = require("randomstring");
const rimraf = require("rimraf");
const docx4js = require('docx4js');
var sppull = require("sppull").sppull;
const storage = require('azure-storage');
///////////////////////////////
// Sequelize database models //
///////////////////////////////
const Sequelize = require('sequelize');
const sequelize = require('../util/database');
const Op = Sequelize.Op;
const ProjectContacts = sequelize.import('../models/db/project_contact');
////////////////////////
// Local dependencies //
////////////////////////
const { parseJsonFile, encrypt, makeDirs, waitForLock, pullFromSharePoint, decrypt, doesFileExistSp } = require('../util/common');
const { getNormalizedFilepath, updateTAndCCleanup, convertDocxToHtml, insertNewTCVersion, waitForFileUpload } = require('../util/update-t-and-c-helper');
const { listContainers, createContainer, uploadString, uploadLocalFile, listBlobs, downloadBlob } = require('../util/blob-helper');
const createError = require('../util/error-management').createErrorFlow;
const { getProjectPath, saveMetadata, copyFileSpToS3Cleanup } = require('../util/copy-to-s3-helper');
const { getTimeTaken, formatLockKey, saveFileToSp, createFolderIfNotExists, createFolderPathRecursively, processExcelFileRequest } = require('../util/common');
const logger = require('../util/logger')(module);
const fileName = req.body.fileName.trim();
const spSite = req.body.spSite;
const spFolder = req.body.spFolder;
const email = req.body.email_address;
const downloadPath = req.body.S3Path;
const spFile = `${spFolder}/${fileName}`;
const before = Date.now();
const uploadFolderName = 'upload';
const siteUrl = `${process.env.SP_URL}/sites/${spSite}/`;
const creds = {
username: process.env.SP_USER,
password: decrypt(process.env.SP_PASSWORD)
};
ProjectContacts.findAll({ where: { can_upload_files: 1, email_address: email }, attributes: ['email_address', 'project_id', 'can_upload_files'] })
.then(projectContacts => {
if (projectContacts.length > 0) { //If email can upload, proceed
doesFileExistSp(creds, spSite, siteUrl, spFile) //Check if file exists in SharePoint
.then(exists => {
if (exists) {
logger.info(`DOWNLOAD PATH: ${downloadPath}`);
logger.info(`FILENAME: ${fileName}`);
const sppullContext = {
siteUrl: siteUrl, //SharePoint URL
creds: {
username: process.env.SP_USER,
password: decrypt(process.env.SP_PASSWORD)
}
};
const sppullOptions = {
spRootFolder: spFolder, // The folder path for the file in SharePoint
dlRootFolder: downloadPath, // Where the file is saved locally
strictObjects: [fileName], // Only download the fileName specified as a query parameter
muteConsole: true
};
pullFromSharePoint(sppullContext, sppullOptions)
.then(filepath => { //Pull file with fileName from SharePoint
logger.info(`FILE NOW IN PATH: ${filepath}`);
// Create the upload directory within the project directory.
const s3UploadFolder = path.join(downloadPath, uploadFolderName);
makeDirs(s3UploadFolder)
.then(() => { //creates upload folder in s3
function saveMetadataCallback(errorObj) { //callback for saveMetadata which checks for errors, semaphore/locks not being used
if (errorObj) {
const filepath = path.join(downloadPath, fileName);
copyFileSpToS3Cleanup(filepath, semaphore, lockKey).then(() => {
const error = createError(errorObj.errorMsg, errorObj.statusCode, errorObj.origErr);
return next(errorObj);
}).catch(errorObj => {
const error = createError(errorObj.errorMsg, errorObj.statusCode, errorObj.origErr);
return next(error);
});
}
}
saveMetadata(saveMetadataCallback); // Save the metadata info.json files.
}).catch(err => {
const filepath = path.join(downloadPath, fileName);
copyFileSpToS3Cleanup(filepath, semaphore, lockKey)
.then(() => {
const error = createError('Unable to create upload directory', 500, err);
return next(error);
}).catch(errorObj => {
const error = createError(errorObj.errorMsg, errorObj.statusCode, errorObj.origErr);
return next(error);
});
});
return res.status(200).json({
message: `${fileName} has been uploaded to ${filepath}`
})
}).catch(errorObj => {
const filepath = path.join(downloadPath, fileName);
copyFileSpToS3Cleanup(filepath, semaphore, lockKey)
.then(() => {
const error = createError(errorObj.errorMsg, errorObj.statusCode, errorObj.origErr);
return next(error);
}).catch(errorObj => {
const error = createError(errorObj.errorMsg, errorObj.statusCode, errorObj.origErr);
return next(error);
});
});
} else {
const error = createError('File does not exist!');
return next(error);
}
}).catch(err => {
const error = createError('File does not exist!');
return next(error);
})
} else {
logger.error(`${email} does not have permission to upload`);
return res.status(401).json({
message: `${email} does not have permission to upload`
});
}
});
1 Answer 1
Got it using promises:
//Finds if project_contact email has permission to upload
function findProjectContacts() {
return new Promise((resolve, reject) => {
ProjectContacts.findAll({ where: { can_upload_files: 1, email_address: email }, attributes: ['email_address', 'project_id', 'can_upload_files'] })
.then(projectContacts => {
if (projectContacts.length > 0) {
return resolve(true);
}
else {
const error = createError(`${email} does not have permission to upload!`, 401);
return reject(error);
}
})
.catch(err => {
const error = createError(`${email} does not have permission to upload!`, 401, err);
return reject(error)
})
})
}
//Checks if file exists in SharePoint
function findFile() {
return new Promise((resolve, reject) => {
doesFileExistSp(creds, spSite, siteUrl, spFile).then(exists => {
if (!exists) {
const error = createError(`${filename} does not exist in ${spFolder}`, 404);
return reject(error);
} else {
return resolve(true);
}
}).catch(err => {
const error = createError(`${filename} does not exist in ${spFolder} `, 404, err);
return reject(error);
});
});
}
//Pulls file from SharePoint to download into specified filepath
function pullFile() {
return new Promise((resolve, reject) => {
const sppullContext = {
siteUrl: siteUrl, //SharePoint URL
creds: creds
};
const sppullOptions = {
spRootFolder: spFolder, // The folder path for the file in SharePoint
dlRootFolder: downloadPath, // Where the file is saved locally
strictObjects: [filename], // Only download the filename specified as a query parameter
muteConsole: true
};
pullFromSharePoint(sppullContext, sppullOptions) //Pull file with filename from SharePoint
.then(filepath => {
if (!fs.existsSync(filepath)) {
const error = createError(`${filepath} does not exist`, 404);
return reject(error);
}
else {
logger.info(`FILE NOW IN PATH: ${filepath}`);
const s3UploadFolder = path.join(downloadPath, uploadFolderName);
makeDirs(s3UploadFolder);
}
return resolve(true);
});
});
}
findProjectContacts()
.then(permission => {
if (permission === true)
return findFile();
})
.then(fileFound => {
if (fileFound === true)
return pullFile();
}).then(fileCopied => {
if (fileCopied === true)
logger.info(`${filename} has been uploaded`);
return res.status(200).json({
message: `${filename} has been uploaded`
});
}).catch(errorObj => {
return next(errorObj);
})
}
creds.password
, then I saw it was fine \$\endgroup\$