Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 32 additions & 13 deletions lib/internal/modules/cjs/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,6 @@ function tryPackage(requestPath, exts, isMain, originalPath) {
err.code = 'MODULE_NOT_FOUND';
err.path = pjsonPath;
err.requestPath = originalPath;
// TODO(BridgeAR): Add the requireStack as well.
throw err;
} else {
process.emitWarning(
Expand Down Expand Up @@ -1406,6 +1405,14 @@ Module._resolveFilename = function(request, parent, isMain, options) {
paths = Module._resolveLookupPaths(request, parent);
}

const requireStack = [];
for (let cursor = parent;
cursor;
// TODO(joyeecheung): it makes more sense to use kLastModuleParent here.
cursor = cursor[kFirstModuleParent]) {
ArrayPrototypePush(requireStack, cursor.filename || cursor.id);
}

if (request[0] === '#' && (parent?.filename || parent?.id === '<repl>')) {
const parentPath = parent?.filename ?? process.cwd() + path.sep;
const pkg = packageJsonReader.getNearestParentPackageJSON(parentPath);
Expand All @@ -1419,7 +1426,7 @@ Module._resolveFilename = function(request, parent, isMain, options) {
);
} catch (e) {
if (e.code === 'ERR_MODULE_NOT_FOUND') {
throw createEsmNotFoundErr(request);
throw createEsmNotFoundErr(request, undefined, requireStack);
}
throw e;
}
Expand All @@ -1428,7 +1435,15 @@ Module._resolveFilename = function(request, parent, isMain, options) {

// Try module self resolution first
const parentPath = trySelfParentPath(parent);
const selfResolved = trySelf(parentPath, request, conditions);
let selfResolved;
try {
selfResolved = trySelf(parentPath, request, conditions);
} catch (e) {
if (e.code === 'MODULE_NOT_FOUND' && e.requireStack === undefined) {
e.requireStack = requireStack;
}
throw e;
}
if (selfResolved) {
const cacheKey = request + '\x00' +
(paths.length === 1 ? paths[0] : ArrayPrototypeJoin(paths, '\x00'));
Expand All @@ -1437,15 +1452,16 @@ Module._resolveFilename = function(request, parent, isMain, options) {
}

// Look up the filename first, since that's the cache key.
const filename = Module._findPath(request, paths, isMain, conditions);
if (filename) { return filename; }
const requireStack = [];
for (let cursor = parent;
cursor;
// TODO(joyeecheung): it makes more sense to use kLastModuleParent here.
cursor = cursor[kFirstModuleParent]) {
ArrayPrototypePush(requireStack, cursor.filename || cursor.id);
let filename;
try {
filename = Module._findPath(request, paths, isMain, conditions);
} catch (e) {
if (e.code === 'MODULE_NOT_FOUND' && e.requireStack === undefined) {
e.requireStack = requireStack;
}
throw e;
}
if (filename) { return filename; }
let message = `Cannot find module '${request}'`;
if (requireStack.length > 0) {
message = message + '\nRequire stack:\n- ' +
Expand Down Expand Up @@ -1485,16 +1501,19 @@ function finalizeEsmResolution(resolved, parentPath, pkgPath) {
* Creates an error object for when a requested ES module cannot be found.
* @param {string} request The name of the requested module
* @param {string} [path] The path to the requested module
* @param {string[]} [requireStack] The require stack at the time of the error
* @returns {Error}
*/
function createEsmNotFoundErr(request, path) {
function createEsmNotFoundErr(request, path, requireStack) {
// eslint-disable-next-line no-restricted-syntax
const err = new Error(`Cannot find module '${request}'`);
err.code = 'MODULE_NOT_FOUND';
if (path) {
err.path = path;
}
// TODO(BridgeAR): Add the requireStack as well.
if (requireStack) {
err.requireStack = requireStack;
}
return err;
}

Expand Down
3 changes: 2 additions & 1 deletion test/parallel/test-module-loading-error.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ assert.throws(
() => { require('../fixtures/packages/is-dir'); },
common.isAIX ? { code: 'ERR_INVALID_PACKAGE_CONFIG' } : {
code: 'MODULE_NOT_FOUND',
message: /Cannot find module '\.\.\/fixtures\/packages\/is-dir'/
message: /Cannot find module '\.\.\/fixtures\/packages\/is-dir'/,
requireStack: [__filename],
}
);
1 change: 1 addition & 0 deletions test/sequential/test-module-loading.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ assert.throws(
message: /packages[/\\]missing-main-no-index[/\\]doesnotexist\.js'\. Please.+package\.json.+valid "main"/,
path: /fixtures[/\\]packages[/\\]missing-main-no-index[/\\]package\.json/,
requestPath: /^\.\.[/\\]fixtures[/\\]packages[/\\]missing-main-no-index$/,
requireStack: [__filename],
}
);

Expand Down
Loading