diff --git a/lib/cli/config.js b/lib/cli/config.js index 011b065510..b7510d7deb 100644 --- a/lib/cli/config.js +++ b/lib/cli/config.js @@ -11,6 +11,7 @@ const fs = require('fs'); const path = require('path'); const debug = require('debug')('mocha:cli:config'); const findUp = require('find-up'); +const {createUnparsableFileError} = require('../errors'); const utils = require('../utils'); /** @@ -81,7 +82,10 @@ exports.loadConfig = filepath => { config = parsers.json(filepath); } } catch (err) { - throw new Error(`failed to parse config "${filepath}": ${err}`); + throw createUnparsableFileError( + `Unable to read/parse ${filepath}: ${err}`, + filepath + ); } return config; }; diff --git a/lib/cli/options.js b/lib/cli/options.js index 95428c4f96..8fa9470e6f 100644 --- a/lib/cli/options.js +++ b/lib/cli/options.js @@ -18,6 +18,7 @@ const {loadConfig, findConfig} = require('./config'); const findUp = require('find-up'); const debug = require('debug')('mocha:cli:options'); const {isNodeFlag} = require('./node-flags'); +const {createUnparsableFileError} = require('../errors'); /** * The `yargs-parser` namespace @@ -190,7 +191,10 @@ const loadPkgRc = (args = {}) => { } } catch (err) { if (args.package) { - throw new Error(`Unable to read/parse ${filepath}: ${err}`); + throw createUnparsableFileError( + `Unable to read/parse ${filepath}: ${err}`, + filepath + ); } debug('failed to read default package.json at %s; ignoring', filepath); } diff --git a/lib/errors.js b/lib/errors.js index 4289676edc..681198ae27 100644 --- a/lib/errors.js +++ b/lib/errors.js @@ -163,7 +163,14 @@ var constants = { * @constant * @default */ - TIMEOUT: 'ERR_MOCHA_TIMEOUT' + TIMEOUT: 'ERR_MOCHA_TIMEOUT', + + /** + * Input file is not able to be parsed + * @constant + * @default + */ + UNPARSABLE_FILE: 'ERR_MOCHA_UNPARSABLE_FILE' }; /** @@ -495,6 +502,20 @@ function createTimeoutError(msg, timeout, file) { return err; } +/** + * Creates an error object to be thrown when file is unparsable + * @public + * @static + * @param {string} message - Error message to be displayed. + * @param {string} filename - File name + * @returns {Error} Error with code {@link constants.UNPARSABLE_FILE} + */ +function createUnparsableFileError(message, filename) { + var err = new Error(message); + err.code = constants.UNPARSABLE_FILE; + return err; +} + /** * Returns `true` if an error came out of Mocha. * _Can suffer from false negatives, but not false positives._ @@ -525,6 +546,7 @@ module.exports = { createMultipleDoneError, createNoFilesMatchPatternError, createTimeoutError, + createUnparsableFileError, createUnsupportedError, deprecate, isMochaError, diff --git a/test/node-unit/cli/config.spec.js b/test/node-unit/cli/config.spec.js index 6f63d508f1..270e3ec95a 100644 --- a/test/node-unit/cli/config.spec.js +++ b/test/node-unit/cli/config.spec.js @@ -109,11 +109,15 @@ describe('cli/config', function() { describe('when config file parsing fails', function() { beforeEach(function() { - sinon.stub(parsers, 'yaml').throws(); + sinon.stub(parsers, 'yaml').throws('goo.yaml is unparsable'); }); it('should throw', function() { - expect(() => loadConfig('goo.yaml'), 'to throw', /failed to parse/); + expect( + () => loadConfig('goo.yaml'), + 'to throw', + 'Unable to read/parse goo.yaml: goo.yaml is unparsable' + ); }); }); }); diff --git a/test/node-unit/cli/options.spec.js b/test/node-unit/cli/options.spec.js index fa376fe286..0455be0aa5 100644 --- a/test/node-unit/cli/options.spec.js +++ b/test/node-unit/cli/options.spec.js @@ -130,7 +130,7 @@ describe('options', function() { beforeEach(function() { readFileSync = sinon.stub(); // package.json - readFileSync.onFirstCall().throws('yikes'); + readFileSync.onFirstCall().throws('bad file message'); findConfig = sinon.stub().returns('/some/.mocharc.json'); loadConfig = sinon.stub().returns({}); findupSync = sinon.stub(); @@ -148,7 +148,7 @@ describe('options', function() { loadOptions('--package /something/wherever --require butts'); }, 'to throw', - /unable to read\/parse/i + 'Unable to read/parse /something/wherever: bad file message' ); }); }); diff --git a/test/unit/errors.spec.js b/test/unit/errors.spec.js index 9c57e55bc2..d610b04acd 100644 --- a/test/unit/errors.spec.js +++ b/test/unit/errors.spec.js @@ -69,6 +69,19 @@ describe('Errors', function() { }); }); + describe('createUnparsableFileError()', function() { + it('should include expected code in thrown unparsable file errors', function() { + expect( + errors.createUnparsableFileError(message, 'badFilePath'), + 'to satisfy', + { + message: message, + code: 'ERR_MOCHA_UNPARSABLE_FILE' + } + ); + }); + }); + describe('deprecate()', function() { var emitWarning;