diff options
author | Thomas <hakerh403@gmail.com> | 2019-12-29 15:56:43 +0300 |
---|---|---|
committer | Ruben Bridgewater <ruben@bridgewater.de> | 2020-01-03 19:47:47 +0300 |
commit | a6c25026867683976f4cc22a62d0009dd26a0220 (patch) | |
tree | 967c7b423a553b6076e300e7ae1ff2b0db9b1005 | |
parent | bd6a29c60b2f82c1883b1ba4c38abd2c3d16b4d4 (diff) |
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: https://github.com/nodejs/node/pull/31129
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Guy Bedford <guybedford@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
-rw-r--r-- | doc/api/errors.md | 5 | ||||
-rw-r--r-- | lib/internal/errors.js | 2 | ||||
-rw-r--r-- | lib/internal/modules/esm/default_resolve.js | 8 | ||||
-rw-r--r-- | test/es-module/test-esm-dynamic-import.js | 16 |
4 files changed, 21 insertions, 10 deletions
diff --git a/doc/api/errors.md b/doc/api/errors.md index 88d982fd195..c5041c796be 100644 --- a/doc/api/errors.md +++ b/doc/api/errors.md @@ -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` diff --git a/lib/internal/errors.js b/lib/internal/errors.js index a0f3f26d5d3..a0b7ee38cf1 100644 --- a/lib/internal/errors.js +++ b/lib/internal/errors.js @@ -1335,6 +1335,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', diff --git a/lib/internal/modules/esm/default_resolve.js b/lib/internal/modules/esm/default_resolve.js index 86e682d28e3..749f6861cd3 100644 --- a/lib/internal/modules/esm/default_resolve.js +++ b/lib/internal/modules/esm/default_resolve.js @@ -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(); @@ -52,8 +53,9 @@ if (experimentalJsonModules) extensionFormatMap['.json'] = legacyExtensionFormatMap['.json'] = 'json'; function resolve(specifier, parentURL) { + let parsed; try { - const parsed = new URL(specifier); + parsed = new URL(specifier); if (parsed.protocol === 'data:') { const [ , mime ] = /^([^/]+\/[^;,]+)(?:[^,]*?)(;base64)?,/.exec(parsed.pathname) || [ null, null, null ]; const format = ({ @@ -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, diff --git a/test/es-module/test-esm-dynamic-import.js b/test/es-module/test-esm-dynamic-import.js index 1fc22f1d989..e60309fe886 100644 --- a/test/es-module/test-esm-dynamic-import.js +++ b/test/es-module/test-esm-dynamic-import.js @@ -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) { @@ -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'); })(); |