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

esm: better error message for unsupported URL #31129

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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions doc/api/errors.md
Expand Up @@ -1957,6 +1957,11 @@ An attempt was made to load a module with an unknown or unsupported format.
An invalid or unknown process signal was passed to an API expecting a valid
signal (such as [`subprocess.kill()`][]).

<a id="ERR_UNSUPPORTED_ESM_URL_SCHEME"></a>
### `ERR_UNSUPPORTED_ESM_URL_SCHEME`

`import` with URL schemes other than `file` and `data` is unsupported.

<a id="ERR_V8BREAKITERATOR"></a>
### `ERR_V8BREAKITERATOR`

Expand Down
2 changes: 2 additions & 0 deletions lib/internal/errors.js
Expand Up @@ -1325,6 +1325,8 @@ E('ERR_UNKNOWN_FILE_EXTENSION',
TypeError);
E('ERR_UNKNOWN_MODULE_FORMAT', 'Unknown module format: %s', RangeError);
E('ERR_UNKNOWN_SIGNAL', 'Unknown signal: %s', TypeError);
E('ERR_UNSUPPORTED_ESM_URL_SCHEME', 'Only file and data URLs are supported ' +
'by the default ESM loader', Error);

E('ERR_V8BREAKITERATOR',
'Full ICU data not installed. See https://github.com/nodejs/node/wiki/Intl',
Expand Down
8 changes: 6 additions & 2 deletions lib/internal/modules/esm/default_resolve.js
Expand Up @@ -21,7 +21,8 @@ const { resolve: moduleWrapResolve,
getPackageType } = internalBinding('module_wrap');
const { URL, pathToFileURL, fileURLToPath } = require('internal/url');
const { ERR_INPUT_TYPE_NOT_ALLOWED,
ERR_UNKNOWN_FILE_EXTENSION } = require('internal/errors').codes;
ERR_UNKNOWN_FILE_EXTENSION,
ERR_UNSUPPORTED_ESM_URL_SCHEME } = require('internal/errors').codes;

const realpathCache = new SafeMap();

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

function resolve(specifier, parentURL) {
let parsed;
try {
const parsed = new URL(specifier);
guybedford marked this conversation as resolved.
Show resolved Hide resolved
parsed = new URL(specifier);
if (parsed.protocol === 'data:') {
const [ , mime ] = /^([^/]+\/[^;,]+)(?:[^,]*?)(;base64)?,/.exec(parsed.pathname) || [ null, null, null ];
const format = ({
Expand All @@ -68,6 +70,8 @@ function resolve(specifier, parentURL) {
};
}
} catch {}
if (parsed && parsed.protocol !== 'file:' && parsed.protocol !== 'data:')
throw new ERR_UNSUPPORTED_ESM_URL_SCHEME();
if (NativeModule.canBeRequiredByUsers(specifier)) {
return {
url: specifier,
Expand Down
16 changes: 8 additions & 8 deletions test/es-module/test-esm-dynamic-import.js
Expand Up @@ -15,8 +15,8 @@ function expectErrorProperty(result, propertyKey, value) {
}));
}

function expectMissingModuleError(result) {
expectErrorProperty(result, 'code', 'ERR_MODULE_NOT_FOUND');
function expectModuleError(result, err) {
expectErrorProperty(result, 'code', err);
}

function expectOkNamespace(result) {
Expand Down Expand Up @@ -56,10 +56,10 @@ function expectFsNamespace(result) {
expectFsNamespace(eval('import("fs")'));
expectFsNamespace(eval('import("fs")'));

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