Skip to content

Commit c10ee5d

Browse files
Hakerh400MylesBorins
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 b95bb38 commit c10ee5d

File tree

4 files changed

+21
-10
lines changed

4 files changed

+21
-10
lines changed

doc/api/errors.md

+5
Original file line numberDiff line numberDiff line change
@@ -1936,6 +1936,11 @@ An attempt was made to load a module with an unknown or unsupported format.
19361936
An invalid or unknown process signal was passed to an API expecting a valid
19371937
signal (such as [`subprocess.kill()`][]).
19381938

1939+
<a id="ERR_UNSUPPORTED_ESM_URL_SCHEME"></a>
1940+
### `ERR_UNSUPPORTED_ESM_URL_SCHEME`
1941+
1942+
`import` with URL schemes other than `file` and `data` is unsupported.
1943+
19391944
<a id="ERR_V8BREAKITERATOR"></a>
19401945
### `ERR_V8BREAKITERATOR`
19411946

lib/internal/errors.js

+2
Original file line numberDiff line numberDiff line change
@@ -1218,6 +1218,8 @@ E('ERR_UNKNOWN_FILE_EXTENSION',
12181218
TypeError);
12191219
E('ERR_UNKNOWN_MODULE_FORMAT', 'Unknown module format: %s', RangeError);
12201220
E('ERR_UNKNOWN_SIGNAL', 'Unknown signal: %s', TypeError);
1221+
E('ERR_UNSUPPORTED_ESM_URL_SCHEME', 'Only file and data URLs are supported ' +
1222+
'by the default ESM loader', Error);
12211223

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

lib/internal/modules/esm/default_resolve.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ const { resolve: moduleWrapResolve,
1717
getPackageType } = internalBinding('module_wrap');
1818
const { URL, pathToFileURL, fileURLToPath } = require('internal/url');
1919
const { ERR_INPUT_TYPE_NOT_ALLOWED,
20-
ERR_UNKNOWN_FILE_EXTENSION } = require('internal/errors').codes;
20+
ERR_UNKNOWN_FILE_EXTENSION,
21+
ERR_UNSUPPORTED_ESM_URL_SCHEME } = require('internal/errors').codes;
2122

2223
const { SafeMap } = primordials;
2324

@@ -50,8 +51,9 @@ if (experimentalJsonModules)
5051
extensionFormatMap['.json'] = legacyExtensionFormatMap['.json'] = 'json';
5152

5253
function resolve(specifier, parentURL) {
54+
let parsed;
5355
try {
54-
const parsed = new URL(specifier);
56+
parsed = new URL(specifier);
5557
if (parsed.protocol === 'data:') {
5658
const [ , mime ] = /^([^/]+\/[^;,]+)(?:[^,]*?)(;base64)?,/.exec(parsed.pathname) || [ null, null, null ];
5759
const format = ({
@@ -66,6 +68,8 @@ function resolve(specifier, parentURL) {
6668
};
6769
}
6870
} catch {}
71+
if (parsed && parsed.protocol !== 'file:' && parsed.protocol !== 'data:')
72+
throw new ERR_UNSUPPORTED_ESM_URL_SCHEME();
6973
if (NativeModule.canBeRequiredByUsers(specifier)) {
7074
return {
7175
url: specifier,

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

+8-8
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ function expectErrorProperty(result, propertyKey, value) {
1717
}));
1818
}
1919

20-
function expectMissingModuleError(result) {
21-
expectErrorProperty(result, 'code', 'ERR_MODULE_NOT_FOUND');
20+
function expectModuleError(result, err) {
21+
expectErrorProperty(result, 'code', err);
2222
}
2323

2424
function expectOkNamespace(result) {
@@ -55,10 +55,10 @@ function expectFsNamespace(result) {
5555
expectFsNamespace(eval('import("fs")'));
5656
expectFsNamespace(eval('import("fs")'));
5757

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

0 commit comments

Comments
 (0)