lib: improve error message for MODULE_NOT_FOUND

Include the require stack in the reported error message.

PR-URL: https://github.com/nodejs/node/pull/25690
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
Ali Ijaz Sheikh 2019-02-13 13:21:10 -08:00
parent 05cd1a0929
commit a02e3e2d5f
8 changed files with 28 additions and 20 deletions

View File

@ -612,8 +612,12 @@ Module._resolveFilename = function(request, parent, isMain, options) {
cursor = cursor.parent) { cursor = cursor.parent) {
requireStack.push(cursor.filename || cursor.id); requireStack.push(cursor.filename || cursor.id);
} }
let message = `Cannot find module '${request}'`;
if (requireStack.length > 0) {
message = message + '\nRequire stack:\n- ' + requireStack.join('\n- ');
}
// eslint-disable-next-line no-restricted-syntax // eslint-disable-next-line no-restricted-syntax
var err = new Error(`Cannot find module '${request}'`); var err = new Error(message);
err.code = 'MODULE_NOT_FOUND'; err.code = 'MODULE_NOT_FOUND';
err.requireStack = requireStack; err.requireStack = requireStack;
throw err; throw err;

View File

@ -15,21 +15,21 @@ assert.strictEqual(
// Verify that existing paths are removed. // Verify that existing paths are removed.
assert.throws(() => { assert.throws(() => {
require.resolve('bar', { paths: [] }) require.resolve('bar', { paths: [] })
}, /^Error: Cannot find module 'bar'$/); }, /^Error: Cannot find module 'bar'/);
// Verify that resolution path can be overwritten. // Verify that resolution path can be overwritten.
{ {
// three.js cannot be loaded from this file by default. // three.js cannot be loaded from this file by default.
assert.throws(() => { assert.throws(() => {
require.resolve('three') require.resolve('three')
}, /^Error: Cannot find module 'three'$/); }, /^Error: Cannot find module 'three'/);
// If the nested-index directory is provided as a resolve path, 'three' // If the nested-index directory is provided as a resolve path, 'three'
// cannot be found because nested-index is used as a starting point and not // cannot be found because nested-index is used as a starting point and not
// a searched directory. // a searched directory.
assert.throws(() => { assert.throws(() => {
require.resolve('three', { paths: [nestedIndex] }) require.resolve('three', { paths: [nestedIndex] })
}, /^Error: Cannot find module 'three'$/); }, /^Error: Cannot find module 'three'/);
// Resolution from nested index directory also checks node_modules. // Resolution from nested index directory also checks node_modules.
assert.strictEqual( assert.strictEqual(

View File

@ -5,7 +5,7 @@ const assert = require('assert');
assert.throws(function() { assert.throws(function() {
require('internal/freelist'); require('internal/freelist');
}, /^Error: Cannot find module 'internal\/freelist'$/); }, /^Error: Cannot find module 'internal\/freelist'/);
assert.strictEqual( assert.strictEqual(
require(fixtures.path('internal-modules')), require(fixtures.path('internal-modules')),

View File

@ -9,7 +9,7 @@ common.expectsError(
require('internal/bootstrap/loaders'); require('internal/bootstrap/loaders');
}, { }, {
code: 'MODULE_NOT_FOUND', code: 'MODULE_NOT_FOUND',
message: 'Cannot find module \'internal/bootstrap/loaders\'' message: /Cannot find module 'internal\/bootstrap\/loaders'/
} }
); );
@ -20,6 +20,6 @@ common.expectsError(
require('owo'); require('owo');
}, { }, {
code: 'MODULE_NOT_FOUND', code: 'MODULE_NOT_FOUND',
message: 'Cannot find module \'owo\'' message: /Cannot find module 'owo'/
} }
); );

View File

@ -80,9 +80,10 @@ common.expectsError(
message: 'The argument \'id\' must be a non-empty string. Received \'\'' message: 'The argument \'id\' must be a non-empty string. Received \'\''
}); });
common.expectsError( assert.throws(
() => { require('../fixtures/packages/is-dir'); }, () => { require('../fixtures/packages/is-dir'); },
{ {
code: 'MODULE_NOT_FOUND', code: 'MODULE_NOT_FOUND',
message: 'Cannot find module \'../fixtures/packages/is-dir\'' message: /Cannot find module '\.\.\/fixtures\/packages\/is-dir'/
}); }
);

View File

@ -35,7 +35,7 @@ fs.writeFileSync(dotfileWithExtension, 'console.log(__filename);', 'utf8');
require(modulePath); require(modulePath);
assert.throws( assert.throws(
() => require(`${modulePath}.foo`), () => require(`${modulePath}.foo`),
new Error(`Cannot find module '${modulePath}.foo'`) (err) => err.message.startsWith(`Cannot find module '${modulePath}.foo'`)
); );
require(`${modulePath}.foo.bar`); require(`${modulePath}.foo.bar`);
delete require.cache[file]; delete require.cache[file];
@ -47,7 +47,7 @@ fs.writeFileSync(dotfileWithExtension, 'console.log(__filename);', 'utf8');
const modulePath = path.join(tmpdir.path, 'test-extensions'); const modulePath = path.join(tmpdir.path, 'test-extensions');
assert.throws( assert.throws(
() => require(modulePath), () => require(modulePath),
new Error(`Cannot find module '${modulePath}'`) (err) => err.message.startsWith(`Cannot find module '${modulePath}'`)
); );
delete require.cache[file]; delete require.cache[file];
Module._pathCache = Object.create(null); Module._pathCache = Object.create(null);
@ -69,7 +69,7 @@ fs.writeFileSync(dotfileWithExtension, 'console.log(__filename);', 'utf8');
const modulePath = path.join(tmpdir.path, 'test-extensions.foo'); const modulePath = path.join(tmpdir.path, 'test-extensions.foo');
assert.throws( assert.throws(
() => require(modulePath), () => require(modulePath),
new Error(`Cannot find module '${modulePath}'`) (err) => err.message.startsWith(`Cannot find module '${modulePath}'`)
); );
delete require.extensions['.foo.bar']; delete require.extensions['.foo.bar'];
Module._pathCache = Object.create(null); Module._pathCache = Object.create(null);

View File

@ -534,6 +534,8 @@ const errorTests = [
expect: [ expect: [
'Thrown:', 'Thrown:',
/^{ Error: Cannot find module 'internal\/repl'/, /^{ Error: Cannot find module 'internal\/repl'/,
/^Require stack:/,
/^- <repl>/,
/^ at .*/, /^ at .*/,
/^ at .*/, /^ at .*/,
/^ at .*/, /^ at .*/,

View File

@ -131,7 +131,7 @@ require('../fixtures/node_modules/foo');
assert.ok(my_path.path_func instanceof Function); assert.ok(my_path.path_func instanceof Function);
// this one does not exist and should throw // this one does not exist and should throw
assert.throws(function() { require('./utils'); }, assert.throws(function() { require('./utils'); },
/^Error: Cannot find module '\.\/utils'$/); /^Error: Cannot find module '\.\/utils'/);
} }
let errorThrown = false; let errorThrown = false;
@ -170,12 +170,13 @@ assert.strictEqual(require('../fixtures/registerExt2').custom, 'passed');
assert.strictEqual(require('../fixtures/foo').foo, 'ok'); assert.strictEqual(require('../fixtures/foo').foo, 'ok');
// Should not attempt to load a directory // Should not attempt to load a directory
try { assert.throws(
() => {
tmpdir.refresh(); tmpdir.refresh();
require(tmpdir.path); require(tmpdir.path);
} catch (err) { },
assert.strictEqual(err.message, `Cannot find module '${tmpdir.path}'`); (err) => err.message.startsWith(`Cannot find module '${tmpdir.path}`)
} );
{ {
// Check load order is as expected // Check load order is as expected