Skip to content

Commit d4eb90e

Browse files
committed
Improved error handling during theme file checks
refs https://github.com/TryGhost/Team/issues/864 - It was unclear what was behind a generic "ValidationError" trown by gscan when investigating the issue - The changes improve: - the error handling is now more granular - catching the prolbe one level closer to the acutal prolbem - error messages describe a little better the stage they fail in - when the error is constructed we included the "err" parameter to have the stack trace available in the logs
1 parent f918691 commit d4eb90e

File tree

4 files changed

+54
-9
lines changed

4 files changed

+54
-9
lines changed

lib/checker.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const Promise = require('bluebird');
22
const _ = require('lodash');
33
const requireDir = require('require-dir');
4+
const {errors} = require('ghost-ignition');
45
const readTheme = require('./read-theme');
56
const versions = require('./utils').versions;
67

@@ -14,6 +15,7 @@ const checks = requireDir('./checks');
1415
* @param {string} themePath
1516
* @param {Object} options
1617
* @param {string} [options.checkVersion] version to check the theme against
18+
* @param {string} [options.themeName] name of the checked theme
1719
* @returns {Promise<Object>}
1820
*/
1921
const checker = function checkAll(themePath, options = {}) {
@@ -32,6 +34,15 @@ const checker = function checkAll(themePath, options = {}) {
3234
return Promise.reduce(_.values(checks), function (theme, check) {
3335
return check(theme, options, themePath);
3436
}, theme);
37+
})
38+
.catch((error) => {
39+
throw new errors.ValidationError({
40+
message: 'Failed theme files check',
41+
help: 'Your theme file structure is corrupted or contains errors',
42+
errorDetails: error.message,
43+
context: options.themeName,
44+
err: error
45+
});
3546
});
3647
};
3748

lib/index.js

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,20 +31,26 @@ const checkZip = async function checkZip(path, options) {
3131

3232
try {
3333
const {path: extractedZipPath} = await readZip(zip);
34-
const theme = await check(extractedZipPath, options);
34+
const theme = await check(extractedZipPath, Object.assign({themeName: zip.name}, options));
3535

3636
if (options.keepExtractedDir) {
3737
return theme;
3838
} else {
39-
return fs.remove(zip.origPath).then(() => theme);
39+
await fs.remove(zip.origPath);
40+
return theme;
4041
}
4142
} catch (error) {
42-
throw new errors.ValidationError({
43-
message: 'Failed to read zip file',
44-
help: 'Your zip file might be corrupted, try unzipping and zipping again.',
45-
errorDetails: error.message,
46-
context: zip.name
47-
});
43+
if (!errors.utils.isIgnitionError(error)) {
44+
throw new errors.ValidationError({
45+
message: 'Failed to check zip file',
46+
help: 'Your zip file might be corrupted, try unzipping and zipping again.',
47+
errorDetails: error.message,
48+
context: zip.name,
49+
err: error
50+
});
51+
}
52+
53+
throw error;
4854
}
4955
};
5056

lib/read-zip.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const Promise = require('bluebird');
44
const os = require('os');
55
const glob = require('glob');
66
const {extract} = require('@tryghost/zip');
7+
const {errors} = require('ghost-ignition');
78
const uuid = require('uuid');
89
const _ = require('lodash');
910

@@ -38,7 +39,14 @@ const readZip = (zip) => {
3839
return zip;
3940
}).catch((err) => {
4041
debug('Zip extraction error', err);
41-
throw err;
42+
43+
throw new errors.ValidationError({
44+
message: 'Failed to read zip file',
45+
help: 'Your zip file might be corrupted, try unzipping and zipping again.',
46+
errorDetails: err.message,
47+
context: zip.name,
48+
err: err
49+
});
4250
});
4351
};
4452

test/general.test.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,25 @@ describe('Check zip', function () {
3535
});
3636
});
3737
});
38+
39+
describe('throws errors', function () {
40+
it('non existing file', async function () {
41+
try {
42+
await checkZip(themePath('030-assets/do_not_exist.zip'));
43+
should.fail(checkZip, 'Should have errored');
44+
} catch (err) {
45+
should.exist(err);
46+
47+
should.exist(err.errorType);
48+
should.equal(err.errorType, 'ValidationError');
49+
50+
should.exist(err.message);
51+
should.equal(err.message, 'Failed to read zip file');
52+
53+
should.exist(err.help);
54+
should.equal(err.help, 'Your zip file might be corrupted, try unzipping and zipping again.');
55+
}
56+
});
57+
});
3858
});
3959

0 commit comments

Comments
 (0)