Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

modules: missing exports as MODULE_NOT_FOUND #28905

Closed
wants to merge 1 commit into from
Closed
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
7 changes: 0 additions & 7 deletions doc/api/errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -1599,13 +1599,6 @@ compiled with ICU support.

A given value is out of the accepted range.

<a id="ERR_PATH_NOT_EXPORTED"></a>
### ERR_PATH_NOT_EXPORTED

> Stability: 1 - Experimental

An attempt was made to load a protected path from a package using `exports`.

<a id="ERR_REQUIRE_ESM"></a>
### ERR_REQUIRE_ESM

Expand Down
4 changes: 2 additions & 2 deletions doc/api/modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,10 +223,10 @@ RESOLVE_BARE_SPECIFIER(DIR, X)
a. Parse DIR/name/package.json, and look for "exports" field.
b. If "exports" is null or undefined, GOTO 3.
c. Find the longest key in "exports" that the subpath starts with.
d. If no such key can be found, throw "not exported".
d. If no such key can be found, throw "not found".
e. If the key matches the subpath entirely, return DIR/name/${exports[key]}.
f. If either the key or exports[key] do not end with a slash (`/`),
throw "not exported".
throw "not found".
g. Return DIR/name/${exports[key]}${subpath.slice(key.length)}.
3. return DIR/X
```
Expand Down
2 changes: 0 additions & 2 deletions lib/internal/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -1104,8 +1104,6 @@ E('ERR_OUT_OF_RANGE',
msg += ` It must be ${range}. Received ${received}`;
return msg;
}, RangeError);
E('ERR_PATH_NOT_EXPORTED',
'Package exports for \'%s\' do not define a \'%s\' subpath', Error);
E('ERR_REQUIRE_ESM', 'Must use import to load ES Module: %s', Error);
E('ERR_SCRIPT_EXECUTION_INTERRUPTED',
'Script execution was interrupted by `SIGINT`', Error);
Expand Down
7 changes: 5 additions & 2 deletions lib/internal/modules/cjs/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ const { compileFunction } = internalBinding('contextify');
const {
ERR_INVALID_ARG_VALUE,
ERR_INVALID_OPT_VALUE,
ERR_PATH_NOT_EXPORTED,
ERR_REQUIRE_ESM
} = require('internal/errors').codes;
const { validateString } = require('internal/validators');
Expand Down Expand Up @@ -377,7 +376,11 @@ function resolveExports(nmPath, request, absoluteRequest) {
return fileURLToPath(resolved);
}
}
throw new ERR_PATH_NOT_EXPORTED(basePath, mappingKey);
// eslint-disable-next-line no-restricted-syntax
const e = new Error(`Package exports for '${basePath}' do not define ` +
`a '${mappingKey}' subpath`);
e.code = 'MODULE_NOT_FOUND';
throw e;
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/module_wrap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -859,7 +859,7 @@ Maybe<URL> PackageExportsResolve(Environment* env,
std::string msg = "Package exports for '" +
URL(".", pjson_url).ToFilePath() + "' do not define a '" + pkg_subpath +
"' subpath, imported from " + base.ToFilePath();
node::THROW_ERR_PATH_NOT_EXPORTED(env, msg.c_str());
node::THROW_ERR_MODULE_NOT_FOUND(env, msg.c_str());
return Nothing<URL>();
}

Expand Down
1 change: 0 additions & 1 deletion src/node_errors.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ void PrintErrorString(const char* format, ...);
V(ERR_MISSING_PLATFORM_FOR_WORKER, Error) \
V(ERR_MODULE_NOT_FOUND, Error) \
V(ERR_OUT_OF_RANGE, RangeError) \
V(ERR_PATH_NOT_EXPORTED, Error) \
V(ERR_SCRIPT_EXECUTION_INTERRUPTED, Error) \
V(ERR_SCRIPT_EXECUTION_TIMEOUT, Error) \
V(ERR_STRING_TOO_LONG, Error) \
Expand Down
6 changes: 3 additions & 3 deletions test/es-module/test-esm-exports.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ import { requireFixture, importFixture } from '../fixtures/pkgexports.mjs';

// There's no such export - so there's nothing to do.
loadFixture('pkgexports/missing').catch(mustCall((err) => {
strictEqual(err.code, 'ERR_PATH_NOT_EXPORTED');
strictEqual(err.code, (isRequire ? '' : 'ERR_') + 'MODULE_NOT_FOUND');
assertStartsWith(err.message, 'Package exports');
assertIncludes(err.message, 'do not define a \'./missing\' subpath');
}));

// The file exists but isn't exported. The exports is a number which counts
// as a non-null value without any properties, just like `{}`.
loadFixture('pkgexports-number/hidden.js').catch(mustCall((err) => {
strictEqual(err.code, 'ERR_PATH_NOT_EXPORTED');
strictEqual(err.code, (isRequire ? '' : 'ERR_') + 'MODULE_NOT_FOUND');
assertStartsWith(err.message, 'Package exports');
assertIncludes(err.message, 'do not define a \'./hidden.js\' subpath');
}));
Expand All @@ -57,7 +57,7 @@ import { requireFixture, importFixture } from '../fixtures/pkgexports.mjs';
// Even though 'pkgexports/sub/asdf.js' works, alternate "path-like" variants
// do not to prevent confusion and accidental loopholes.
loadFixture('pkgexports/sub/./../asdf.js').catch(mustCall((err) => {
strictEqual(err.code, 'ERR_PATH_NOT_EXPORTED');
strictEqual(err.code, (isRequire ? '' : 'ERR_') + 'MODULE_NOT_FOUND');
assertStartsWith(err.message, 'Package exports');
assertIncludes(err.message,
'do not define a \'./sub/./../asdf.js\' subpath');
Expand Down