🥅 Clearer info about any errors found in the config

This should make it easier for users to understand exactly where an issue is, and give clear instructions on how to fix it
This commit is contained in:
Alicia Sykes 2022-02-09 20:05:56 +00:00
parent 45edc9731a
commit c3b93e4164
1 changed files with 57 additions and 24 deletions

View File

@ -1,8 +1,11 @@
/* eslint-disable no-console */
/* Script that validates the conf.yml file against Dashy's schema, and outputs any issues */
const Ajv = require('ajv');
const yaml = require('js-yaml');
const fs = require('fs');
/**
* Checks that conf.yml is present + parsable, then validates it against the schema
* Prints detailed info about any errors or warnings to help the user fix the issue
*/
const fs = require('fs'); // For opening + reading files
const yaml = require('js-yaml'); // For parsing YAML
const Ajv = require('ajv'); // For validating with schema
const schema = require('../src/utils/ConfigSchema.json');
@ -17,32 +20,29 @@ const validatorOptions = {
const ajv = new Ajv(validatorOptions);
/* Message printed when validation was successful */
const successMsg = () => '\x1b[1m\x1b[32mNo issues found, your configuration is valid :)\x1b[0m\n';
const successMsg = () => '\x1b[1m\x1b[32m✔️ Config file is valid, no issues found\x1b[0m\n';
/* Just a wrapper to system's console.log */
const logToConsole = (msg) => { console.log(msg); };
const logToConsole = (msg) => { console.log(msg || '\n'); }; // eslint-disable-line no-console
/* Formats error message. ready for printing to the console */
const errorMsg = (output) => {
const warningFont = '\x1b[103m\x1b[34m';
const line = `${warningFont}${new Array(42).fill('━').join('')}\x1b[0m`;
const formatParams = (params) => {
if (params.additionalProperty) return `(${params.additionalProperty})`;
return '';
};
let msg = `\n${line}\n${warningFont} Warning: ${output.length} `
+ `issue${output.length > 1 ? 's' : ''} found in config file \x1b[0m\n${line}\n`;
output.forEach((details, index) => {
msg += `${'\x1b[36m'}${index + 1}. ${details.keyword} ${details.message} `
+ `in ${details.instancePath}\x1b[0m\n`;
msg += `${'\x1b[36m'}${index + 1}. \x1b[4m${details.instancePath}\x1b[0m\x1b[36m `
+ `${details.message} ${formatParams(details.params)}\x1b[0m\n`;
});
return msg;
};
/* Error message printed when the file could not be opened */
const bigError = () => {
const formatting = '\x1b[30m\x1b[43m';
const line = `${formatting}${new Array(38).fill('━').join('')}\x1b[0m\n`;
const msg = `${formatting} Error, unable to validate 'conf.yml' \x1b[0m\n`;
return `\n${line}${msg}${line}\n`;
};
/* Sets valid status as environmental variable */
const setIsValidVariable = (isValid) => {
process.env.VUE_APP_CONFIG_VALID = isValid;
};
@ -60,16 +60,49 @@ const validate = (config) => {
}
};
try {
/* Error message printed when the file could not be opened */
const bigError = () => {
const formatting = '\x1b[30m\x1b[43m';
const line = `${formatting}${new Array(38).fill('━').join('')}\x1b[0m\n`;
const msg = `${formatting} Error, unable to validate 'conf.yml' \x1b[0m\n`;
return `\n${line}${msg}${line}`;
};
/* Given an error object, prints helpful info to the user */
const printFileReadError = (e) => {
let customError = '';
if (e.mark) { // YAML syntax error
customError = `\x1b[33m\x1b[4m⚠ Error on line ${e.mark.line}, column ${e.mark.column}: `
+ `${e.reason}\x1b[0m\n\n${e.mark.snippet}\n\x1b[0m`
+ '\n\x1b[36m You might find it helpful to use a YAML validator'
+ ', like: \x1b[4mhttps://yamlchecker.com/\x1b[0m\n';
}
if (e.code === 'ENOENT') { // File not found error
customError = `\x1b[33m⚠ Config file could not be found at ${e.path}\x1b[0m\n`;
}
if (e.code === 'EISDIR') { // Not a file
customError = '\x1b[33m⚠ Config needs to be a file, but found a directory instead \x1b[0m\n';
}
if (e.code === 'EACCES' || e.code === 'EPERM') { // File permissions error
customError = '\x1b[33m⚠ Permission denied \x1b[0m\n';
}
logToConsole(customError);
if (customError === '') { // Unknown error, print stack trace
const moreInfo = 'Ensure that your config file is present, readable, and valid YAML. '
+ 'If this issue persists, you can get support by raising a ticket on GitHub. '
+ 'Please include the following stack trace';
logToConsole(moreInfo);
// eslint-disable-next-line no-console
console.warn('\x1b[33mStack Trace for config-validator.js:\x1b[0m\n', e);
logToConsole();
}
};
try { // Try to open and parse the YAML file
const config = yaml.load(fs.readFileSync('./public/conf.yml', 'utf8'));
validate(config);
} catch (e) { // Something went very wrong...
setIsValidVariable(false);
logToConsole(bigError());
logToConsole('Please ensure that your config file is present, '
+ 'has the correct access rights and is parsable. '
+ 'If this warning persists, it may be an issue with the '
+ 'validator function. Please raise an issue, and include the following stack trace:\n');
console.warn('\x1b[33mStack Trace for config-validator.js:\x1b[0m\n', e);
logToConsole('\n\n');
printFileReadError(e);
}