Skip to content

Commit a6c2502

Browse files
Hakerh400BridgeAR
authored andcommitted
esm: better error message for unsupported URL
The default ESM loader supports only file and data URLs. This PR adds better error message for it. PR-URL: #31129 Reviewed-By: Gus Caplan <[email protected]> Reviewed-By: Guy Bedford <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Rich Trott <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]>
1 parent bd6a29c commit a6c2502

File tree

4 files changed

+21
-10
lines changed

4 files changed

+21
-10
lines changed

doc/api/errors.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1957,6 +1957,11 @@ An attempt was made to load a module with an unknown or unsupported format.
19571957
An invalid or unknown process signal was passed to an API expecting a valid
19581958
signal (such as [`subprocess.kill()`][]).
19591959

1960+
<a id="ERR_UNSUPPORTED_ESM_URL_SCHEME"></a>
1961+
### `ERR_UNSUPPORTED_ESM_URL_SCHEME`
1962+
1963+
`import` with URL schemes other than `file` and `data` is unsupported.
1964+
19601965
<a id="ERR_V8BREAKITERATOR"></a>
19611966
### `ERR_V8BREAKITERATOR`
19621967

lib/internal/errors.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1335,6 +1335,8 @@ E('ERR_UNKNOWN_FILE_EXTENSION',
13351335
TypeError);
13361336
E('ERR_UNKNOWN_MODULE_FORMAT', 'Unknown module format: %s', RangeError);
13371337
E('ERR_UNKNOWN_SIGNAL', 'Unknown signal: %s', TypeError);
1338+
E('ERR_UNSUPPORTED_ESM_URL_SCHEME', 'Only file and data URLs are supported ' +
1339+
'by the default ESM loader', Error);
13381340

13391341
E('ERR_V8BREAKITERATOR',
13401342
'Full ICU data not installed. See https://github.com/nodejs/node/wiki/Intl',

lib/internal/modules/esm/default_resolve.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ const { resolve: moduleWrapResolve,
2121
getPackageType } = internalBinding('module_wrap');
2222
const { URL, pathToFileURL, fileURLToPath } = require('internal/url');
2323
const { ERR_INPUT_TYPE_NOT_ALLOWED,
24-
ERR_UNKNOWN_FILE_EXTENSION } = require('internal/errors').codes;
24+
ERR_UNKNOWN_FILE_EXTENSION,
25+
ERR_UNSUPPORTED_ESM_URL_SCHEME } = require('internal/errors').codes;
2526

2627
const realpathCache = new SafeMap();
2728

@@ -52,8 +53,9 @@ if (experimentalJsonModules)
5253
extensionFormatMap['.json'] = legacyExtensionFormatMap['.json'] = 'json';
5354

5455
function resolve(specifier, parentURL) {
56+
let parsed;
5557
try {
56-
const parsed = new URL(specifier);
58+
parsed = new URL(specifier);
5759
if (parsed.protocol === 'data:') {
5860
const [ , mime ] = /^([^/]+\/[^;,]+)(?:[^,]*?)(;base64)?,/.exec(parsed.pathname) || [ null, null, null ];
5961
const format = ({
@@ -68,6 +70,8 @@ function resolve(specifier, parentURL) {
6870
};
6971
}
7072
} catch {}
73+
if (parsed && parsed.protocol !== 'file:' && parsed.protocol !== 'data:')
74+
throw new ERR_UNSUPPORTED_ESM_URL_SCHEME();
7175
if (NativeModule.canBeRequiredByUsers(specifier)) {
7276
return {
7377
url: specifier,

test/es-module/test-esm-dynamic-import.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ function expectErrorProperty(result, propertyKey, value) {
1515
}));
1616
}
1717

18-
function expectMissingModuleError(result) {
19-
expectErrorProperty(result, 'code', 'ERR_MODULE_NOT_FOUND');
18+
function expectModuleError(result, err) {
19+
expectErrorProperty(result, 'code', err);
2020
}
2121

2222
function expectOkNamespace(result) {
@@ -56,10 +56,10 @@ function expectFsNamespace(result) {
5656
expectFsNamespace(eval('import("fs")'));
5757
expectFsNamespace(eval('import("fs")'));
5858

59-
expectMissingModuleError(import('./not-an-existing-module.mjs'));
60-
// TODO(jkrems): Right now this doesn't hit a protocol error because the
61-
// module resolution step already rejects it. These arguably should be
62-
// protocol errors.
63-
expectMissingModuleError(import('node:fs'));
64-
expectMissingModuleError(import('http://example.com/foo.js'));
59+
expectModuleError(import('./not-an-existing-module.mjs'),
60+
'ERR_MODULE_NOT_FOUND');
61+
expectModuleError(import('node:fs'),
62+
'ERR_UNSUPPORTED_ESM_URL_SCHEME');
63+
expectModuleError(import('http://example.com/foo.js'),
64+
'ERR_UNSUPPORTED_ESM_URL_SCHEME');
6565
})();

0 commit comments

Comments
 (0)