Skip to content

Commit

Permalink
errors: don't rekey on primitive type
Browse files Browse the repository at this point in the history
If an error is thrown before a module is loaded, we attempt to cache
source map against error object, rather than module object. We
can't do this if the error is a primitive type

Fixes nodejs#38945
  • Loading branch information
bcoe committed Jun 13, 2021
1 parent 4e17ffc commit 773ea75
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 1 deletion.
6 changes: 5 additions & 1 deletion lib/internal/source_map/source_map_cache.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,11 @@ function sourcesToAbsolute(baseURL, data) {
// Move source map from garbage collected module to alternate key.
function rekeySourceMap(cjsModuleInstance, newInstance) {
const sourceMap = cjsSourceMapCache.get(cjsModuleInstance);
if (sourceMap) {
// If an exception occurs before a module finishes loading it will removed
// from the module cache and our WeakMap. To allow a source map to still be
// applied to the stack trace when this happens, we rekey on the thrown error.
// This is only possible if the error is an object and not a primitive type.
if (sourceMap && typeof newInstance === 'object') {
cjsSourceMapCache.set(newInstance, sourceMap);
}
}
Expand Down
8 changes: 8 additions & 0 deletions test/fixtures/source-map/throw-string-original.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
* comments dropped by uglify.
*/
function Hello() {
throw 'goodbye';
}

Hello();
2 changes: 2 additions & 0 deletions test/fixtures/source-map/throw-string.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions test/parallel/test-source-map-enable.js
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,23 @@ function nextdir() {
assert.ok(sourceMap);
}

// Does not attempt to rekey source map on primitive type.
{
const coverageDirectory = nextdir();
const output = spawnSync(process.execPath, [
'--enable-source-maps',
require.resolve('../fixtures/source-map/throw-string.js'),
], { env: { ...process.env, NODE_V8_COVERAGE: coverageDirectory } });
const sourceMap = getSourceMapFromCache(
'throw-string.js',
coverageDirectory
);
// Original stack trace.
assert.match(output.stderr.toString(), /goodbye/);
// Source map should have been serialized.
assert.ok(sourceMap);
}

function getSourceMapFromCache(fixtureFile, coverageDirectory) {
const jsonFiles = fs.readdirSync(coverageDirectory);
for (const jsonFile of jsonFiles) {
Expand Down

0 comments on commit 773ea75

Please sign in to comment.