diff --git a/lib/internal/modules/esm/resolve.js b/lib/internal/modules/esm/resolve.js index 03725bd0b5dfbe..0d277915b3a01f 100644 --- a/lib/internal/modules/esm/resolve.js +++ b/lib/internal/modules/esm/resolve.js @@ -231,7 +231,15 @@ function finalizeResolution(resolved, base, preserveSymlinks) { fileURLToPath(base)); } - const path = fileURLToPath(resolved); + let path; + try { + path = fileURLToPath(resolved); + } catch (err) { + const { setOwnProperty } = require('internal/util'); + setOwnProperty(err, 'input', `${resolved}`); + setOwnProperty(err, 'module', `${base}`); + throw err; + } const stats = internalModuleStat(toNamespacedPath(StringPrototypeEndsWith(path, '/') ? StringPrototypeSlice(path, -1) : path)); diff --git a/test/es-module/test-esm-loader-default-resolver.mjs b/test/es-module/test-esm-loader-default-resolver.mjs index 27320fcfcfe862..2a69010e05047f 100644 --- a/test/es-module/test-esm-loader-default-resolver.mjs +++ b/test/es-module/test-esm-loader-default-resolver.mjs @@ -49,4 +49,18 @@ describe('default resolver', () => { assert.strictEqual(stdout.trim(), 'index.byoe!'); assert.strictEqual(stderr, ''); }); + + it('should identify the parent module of an invalid URL host in import specifier', async () => { + if (process.platform === 'win32') return; + + const { code, stderr } = await spawnPromisified(execPath, [ + '--no-warnings', + fixtures.path('es-modules', 'invalid-posix-host.mjs'), + ]); + + assert.match(stderr, /ERR_INVALID_FILE_URL_HOST/); + assert.match(stderr, /file:\/\/hmm\.js/); + assert.match(stderr, /invalid-posix-host\.mjs/); + assert.strictEqual(code, 1); + }); }); diff --git a/test/fixtures/es-modules/invalid-posix-host.mjs b/test/fixtures/es-modules/invalid-posix-host.mjs new file mode 100644 index 00000000000000..65ebb2c0496c15 --- /dev/null +++ b/test/fixtures/es-modules/invalid-posix-host.mjs @@ -0,0 +1 @@ +import "file://hmm.js";