ImportHandler: Throw Errors, not strings

This commit is contained in:
Richard Hansen 2021-02-07 19:21:53 -05:00 committed by John McLear
parent 908635a1de
commit 0ff131bbbb

View file

@ -33,6 +33,18 @@ const importEtherpad = require('../utils/ImportEtherpad');
const log4js = require('log4js'); const log4js = require('log4js');
const hooks = require('../../static/js/pluginfw/hooks.js'); const hooks = require('../../static/js/pluginfw/hooks.js');
// `status` must be a string supported by `importErrorMessage()` in `src/static/js/pad_impexp.js`.
class ImportError extends Error {
constructor(status, ...args) {
super(...args);
if (Error.captureStackTrace) Error.captureStackTrace(this, ImportError);
this.name = 'ImportError';
this.status = status;
const msg = this.message == null ? '' : String(this.message);
if (status !== '') this.message = msg === '' ? status : `${status}: ${msg}`;
}
}
const rm = async (path) => { const rm = async (path) => {
try { try {
await fs.unlink(path); await fs.unlink(path);
@ -99,13 +111,13 @@ const doImport = async (req, res, padId) => {
// I hate doing indexOf here but I can't see anything to use... // I hate doing indexOf here but I can't see anything to use...
if (err && err.stack && err.stack.indexOf('maxFileSize') !== -1) { if (err && err.stack && err.stack.indexOf('maxFileSize') !== -1) {
return reject('maxFileSize'); return reject(new ImportError('maxFileSize'));
} }
return reject('uploadFailed'); return reject(new ImportError('uploadFailed'));
} }
if (!files.file) { // might not be a graceful fix but it works if (!files.file) { // might not be a graceful fix but it works
return reject('uploadFailed'); return reject(new ImportError('uploadFailed'));
} }
resolve(files.file.path); resolve(files.file.path);
}); });
@ -129,7 +141,7 @@ const doImport = async (req, res, padId) => {
await fs.rename(oldSrcFile, srcFile); await fs.rename(oldSrcFile, srcFile);
} else { } else {
console.warn('Not allowing unknown file type to be imported', fileEnding); console.warn('Not allowing unknown file type to be imported', fileEnding);
throw 'uploadFailed'; throw new ImportError('uploadFailed');
} }
} }
@ -150,7 +162,7 @@ const doImport = async (req, res, padId) => {
if (headCount >= 10) { if (headCount >= 10) {
apiLogger.warn('Aborting direct database import attempt of a pad that already has content'); apiLogger.warn('Aborting direct database import attempt of a pad that already has content');
throw 'padHasData'; throw new ImportError('padHasData');
} }
const _text = await fs.readFile(srcFile, 'utf8'); const _text = await fs.readFile(srcFile, 'utf8');
@ -176,7 +188,7 @@ const doImport = async (req, res, padId) => {
// catch convert errors // catch convert errors
if (err) { if (err) {
console.warn('Converting Error:', err); console.warn('Converting Error:', err);
return reject('convertFailed'); return reject(new ImportError('convertFailed'));
} }
resolve(); resolve();
}); });
@ -192,7 +204,7 @@ const doImport = async (req, res, padId) => {
const isAscii = !Array.prototype.some.call(buf, (c) => (c > 240)); const isAscii = !Array.prototype.some.call(buf, (c) => (c > 240));
if (!isAscii) { if (!isAscii) {
throw 'uploadFailed'; throw new ImportError('uploadFailed');
} }
} }
@ -256,15 +268,8 @@ exports.doImport = (req, res, padId) => {
*/ */
let status = 'ok'; let status = 'ok';
doImport(req, res, padId).catch((err) => { doImport(req, res, padId).catch((err) => {
// check for known errors and replace the status if (!(err instanceof ImportError) || !err.status) throw err;
if (err === 'uploadFailed' || status = err.status;
err === 'convertFailed' ||
err === 'padHasData' ||
err === 'maxFileSize') {
status = err;
} else {
throw err;
}
}).then(() => { }).then(() => {
// close the connection // close the connection
res.send(`<script>document.addEventListener('DOMContentLoaded', function(){ var impexp = window.parent.padimpexp.handleFrameCall('${req.directDatabaseAccess}', '${status}'); })</script>`); res.send(`<script>document.addEventListener('DOMContentLoaded', function(){ var impexp = window.parent.padimpexp.handleFrameCall('${req.directDatabaseAccess}', '${status}'); })</script>`);