From 8778d7c38fa17d005a6269980483f9e1430e716f Mon Sep 17 00:00:00 2001 From: Patrick Steele-idem Date: Wed, 14 Feb 2018 15:07:31 -0800 Subject: [PATCH] Fixes #1023 - Load exceptions in user resolvers are not reported --- tests/files/load-error-resolver.js | 1 + tests/src/core/resolve.js | 16 +++++++++++ utils/resolve.js | 43 +++++++++++++++++------------- 3 files changed, 42 insertions(+), 18 deletions(-) create mode 100644 tests/files/load-error-resolver.js diff --git a/tests/files/load-error-resolver.js b/tests/files/load-error-resolver.js new file mode 100644 index 000000000..aa9d33010 --- /dev/null +++ b/tests/files/load-error-resolver.js @@ -0,0 +1 @@ +throw new Error('TEST ERROR') diff --git a/tests/src/core/resolve.js b/tests/src/core/resolve.js index 307befcde..3c15303ed 100644 --- a/tests/src/core/resolve.js +++ b/tests/src/core/resolve.js @@ -118,6 +118,22 @@ describe('resolve', function () { )).to.equal(utils.testFilePath('./jsx/MyCoolComponent.jsx')) }) + it('reports load exception in a user resolver', function () { + + const testContext = utils.testContext({ 'import/resolver': './load-error-resolver' }) + const testContextReports = [] + testContext.report = function (reportInfo) { + testContextReports.push(reportInfo) + } + + expect(resolve( '../files/exception' + , Object.assign({}, testContext, { getFilename: function () { return utils.getFilename('exception.js') } }) + )).to.equal(undefined) + expect(testContextReports[0]).to.be.an('object') + expect(testContextReports[0].message).to.equal('Resolve error: TEST ERROR') + expect(testContextReports[0].loc).to.eql({ line: 1, column: 0 }) + }) + const caseDescribe = (!CASE_SENSITIVE_FS ? describe : describe.skip) caseDescribe('case sensitivity', function () { let file diff --git a/utils/resolve.js b/utils/resolve.js index 8193e7731..b280ca2cf 100644 --- a/utils/resolve.js +++ b/utils/resolve.js @@ -14,6 +14,20 @@ exports.CASE_SENSITIVE_FS = CASE_SENSITIVE_FS const fileExistsCache = new ModuleCache() +function tryRequire(target) { + let resolved; + try { + // Check if the target exists + resolved = require.resolve(target); + } catch(e) { + // If the target does not exist then just return undefined + return undefined; + } + + // If the target exists then return the loaded module + return require(resolved); +} + // http://stackoverflow.com/a/27382838 exports.fileExistsWithCaseSync = function fileExistsWithCaseSync(filepath, cacheSettings) { // don't care if the FS is case-sensitive @@ -135,27 +149,20 @@ function resolverReducer(resolvers, map) { throw new Error('invalid resolver config') } +function getBaseDir(sourceFile) { + return pkgDir.sync(sourceFile) || process.cwd() +} function requireResolver(name, sourceFile) { // Try to resolve package with conventional name - try { - return require(`eslint-import-resolver-${name}`) - } catch (err) { /* continue */ } + let resolver = tryRequire(`eslint-import-resolver-${name}`) || + tryRequire(name) || + tryRequire(path.resolve(getBaseDir(sourceFile), name)) - // Try to resolve package with custom name (@myorg/resolver-name) - try { - return require(name) - } catch (err) { /* continue */ } - - // Try to resolve package with path, relative to closest package.json - // or current working directory - try { - const baseDir = pkgDir.sync(sourceFile) || process.cwd() - // absolute paths ignore base, so this covers both - return require(path.resolve(baseDir, name)) - } catch (err) { /* continue */ } - - // all else failed - throw new Error(`unable to load resolver "${name}".`) + if (!resolver) { + throw new Error(`unable to load resolver "${name}".`) + } else { + return resolver; + } } const erroredContexts = new Set()