diff --git a/lib/internal/modules/esm/module_job.js b/lib/internal/modules/esm/module_job.js index 15bdbf3bfc6a66..0ef8ebdeb9245b 100644 --- a/lib/internal/modules/esm/module_job.js +++ b/lib/internal/modules/esm/module_job.js @@ -133,9 +133,14 @@ class ModuleJob { StringPrototypeIncludes(e.message, ' does not provide an export named')) { const splitStack = StringPrototypeSplit(e.stack, '\n'); - const parentFileUrl = splitStack[0]; - const [, childSpecifier, name] = StringPrototypeMatch(e.message, - /module '(.*)' does not provide an export named '(.+)'/); + const parentFileUrl = StringPrototypeReplace( + splitStack[0], + /:\d+$/, + '' + ); + const { 1: childSpecifier, 2: name } = StringPrototypeMatch( + e.message, + /module '(.*)' does not provide an export named '(.+)'/); const childFileURL = await this.loader.resolve(childSpecifier, parentFileUrl); const format = await this.loader.getFormat(childFileURL); diff --git a/test/fixtures/policy/bad-main.mjs b/test/fixtures/policy/bad-main.mjs new file mode 100644 index 00000000000000..db1938ad7c2e87 --- /dev/null +++ b/test/fixtures/policy/bad-main.mjs @@ -0,0 +1 @@ +import {doesNotExist} from './dep.js'; diff --git a/test/fixtures/policy/dependencies/dependencies-missing-export-policy.json b/test/fixtures/policy/dependencies/dependencies-missing-export-policy.json new file mode 100644 index 00000000000000..5da0de13920936 --- /dev/null +++ b/test/fixtures/policy/dependencies/dependencies-missing-export-policy.json @@ -0,0 +1,11 @@ +{ + "resources": { + "../bad-main.mjs": { + "integrity": true, + "dependencies": true + }, + "../dep.js": { + "integrity": true + } + } +} diff --git a/test/parallel/test-policy-dependencies.js b/test/parallel/test-policy-dependencies.js index 4486e0f8aa08c0..157da8295266db 100644 --- a/test/parallel/test-policy-dependencies.js +++ b/test/parallel/test-policy-dependencies.js @@ -89,3 +89,23 @@ const dep = fixtures.path('policy', 'parent.js'); ); assert.strictEqual(status, 1); } +{ + // Regression test for https://github.com/nodejs/node/issues/37812 + const depPolicy = fixtures.path( + 'policy', + 'dependencies', + 'dependencies-missing-export-policy.json'); + const { status, stderr } = spawnSync( + process.execPath, + [ + '--experimental-policy', + depPolicy, + fixtures.path('policy', 'bad-main.mjs'), + ] + ); + assert.strictEqual(status, 1); + assert.match( + `${stderr}`, + /SyntaxError: Named export 'doesNotExist' not found\./, + 'Should give the real SyntaxError and position'); +}