diff --git a/lib/internal/modules/esm/module_job.js b/lib/internal/modules/esm/module_job.js index b899c233d45a09..0ef8ebdeb9245b 100644 --- a/lib/internal/modules/esm/module_job.js +++ b/lib/internal/modules/esm/module_job.js @@ -24,6 +24,9 @@ const { const { ModuleWrap } = internalBinding('module_wrap'); const { decorateErrorStack } = require('internal/util'); +const { + getSourceMapsEnabled, +} = require('internal/source_map/source_map_cache'); const assert = require('internal/assert'); const resolvedPromise = PromiseResolve(); @@ -122,7 +125,12 @@ class ModuleJob { } } catch (e) { decorateErrorStack(e); - if (StringPrototypeIncludes(e.message, + // TODO(@bcoe): Add source map support to exception that occurs as result + // of missing named export. This is currently not possible because + // stack trace originates in module_job, not the file itself. A hidden + // symbol with filename could be set in node_errors.cc to facilitate this. + if (!getSourceMapsEnabled() && + StringPrototypeIncludes(e.message, ' does not provide an export named')) { const splitStack = StringPrototypeSplit(e.stack, '\n'); const parentFileUrl = StringPrototypeReplace( diff --git a/test/fixtures/source-map/esm-export-missing-module.mjs b/test/fixtures/source-map/esm-export-missing-module.mjs new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/test/fixtures/source-map/esm-export-missing-module.mjs.map b/test/fixtures/source-map/esm-export-missing-module.mjs.map new file mode 100644 index 00000000000000..17417c928dc04d --- /dev/null +++ b/test/fixtures/source-map/esm-export-missing-module.mjs.map @@ -0,0 +1 @@ +{"version":3,"file":"esm-export-missing-module.esm","sourceRoot":"","sources":["./exm-export-missing-module.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,SAAS;AAEzB,CAAC"} \ No newline at end of file diff --git a/test/fixtures/source-map/esm-export-missing.mjs b/test/fixtures/source-map/esm-export-missing.mjs new file mode 100644 index 00000000000000..4bda755a86b389 --- /dev/null +++ b/test/fixtures/source-map/esm-export-missing.mjs @@ -0,0 +1,2 @@ +import { Something } from './esm-export-missing-module.mjs'; +//# sourceMappingURL=esm-export-missing.mjs.map diff --git a/test/fixtures/source-map/esm-export-missing.mjs.map b/test/fixtures/source-map/esm-export-missing.mjs.map new file mode 100644 index 00000000000000..2d1d482dc97083 --- /dev/null +++ b/test/fixtures/source-map/esm-export-missing.mjs.map @@ -0,0 +1 @@ +{"version":3,"file":"esm-export-missing.ts","sourceRoot":"","sources":["./esm-export-missing.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC"} \ No newline at end of file diff --git a/test/fixtures/source-map/esm-export-missing.ts b/test/fixtures/source-map/esm-export-missing.ts new file mode 100644 index 00000000000000..14797c69feaebc --- /dev/null +++ b/test/fixtures/source-map/esm-export-missing.ts @@ -0,0 +1,3 @@ + +import { Something } from './exm-export-missing-module.mjs'; +console.info(Something); diff --git a/test/parallel/test-source-map-enable.js b/test/parallel/test-source-map-enable.js index e0c222d1a333bf..eab718813fc379 100644 --- a/test/parallel/test-source-map-enable.js +++ b/test/parallel/test-source-map-enable.js @@ -324,6 +324,25 @@ function nextdir() { assert.ok(sourceMap); } +// Does not throw TypeError when exception occurs as result of missing named +// export. +{ + const coverageDirectory = nextdir(); + const output = spawnSync(process.execPath, [ + '--enable-source-maps', + require.resolve('../fixtures/source-map/esm-export-missing.mjs'), + ], { env: { ...process.env, NODE_V8_COVERAGE: coverageDirectory } }); + const sourceMap = getSourceMapFromCache( + 'esm-export-missing.mjs', + coverageDirectory + ); + // Module loader error displayed. + assert.match(output.stderr.toString(), + /does not provide an export named 'Something'/); + // Source map should have been serialized. + assert.ok(sourceMap); +} + function getSourceMapFromCache(fixtureFile, coverageDirectory) { const jsonFiles = fs.readdirSync(coverageDirectory); for (const jsonFile of jsonFiles) {