From 63b5c498716afc7b017b2261416534ab414c34c3 Mon Sep 17 00:00:00 2001 From: legendecas Date: Sat, 6 Aug 2022 19:56:27 +0800 Subject: [PATCH] src,lib: print prinstine source when source map source not found Print unmapped source lines when the source map source is not found. Error stacks should be correctly mapped even when the source is absent. PR-URL: https://github.com/nodejs/node/pull/44052 Refs: https://github.com/nodejs/node/pull/44019 Reviewed-By: Ben Coe --- lib/internal/source_map/prepare_stack_trace.js | 13 +++++++------ src/node_errors.cc | 4 +++- test/fixtures/source-map/no-source.js | 9 +++++++++ test/fixtures/source-map/no-source.js.map | 1 + test/fixtures/source-map/no-source.ts | 10 ++++++++++ test/message/source_map_no_source_file.js | 6 ++++++ test/message/source_map_no_source_file.out | 17 +++++++++++++++++ 7 files changed, 53 insertions(+), 7 deletions(-) create mode 100644 test/fixtures/source-map/no-source.js create mode 100644 test/fixtures/source-map/no-source.js.map create mode 100644 test/fixtures/source-map/no-source.ts create mode 100644 test/message/source_map_no_source_file.js create mode 100644 test/message/source_map_no_source_file.out diff --git a/lib/internal/source_map/prepare_stack_trace.js b/lib/internal/source_map/prepare_stack_trace.js index d01ca2bedd52b8..7f184545cd8843 100644 --- a/lib/internal/source_map/prepare_stack_trace.js +++ b/lib/internal/source_map/prepare_stack_trace.js @@ -139,7 +139,6 @@ function getErrorSource( originalLine, originalColumn ) { - let exceptionLine = ''; const originalSourcePathNoScheme = StringPrototypeStartsWith(originalSourcePath, 'file://') ? fileURLToPath(originalSourcePath) : originalSourcePath; @@ -147,9 +146,14 @@ function getErrorSource( sourceMap.payload, originalSourcePath ); + if (typeof source !== 'string') { + return; + } const lines = RegExpPrototypeSymbolSplit(/\r?\n/, source, originalLine + 1); const line = lines[originalLine]; - if (!line) return exceptionLine; + if (!line) { + return; + } // Display ^ in appropriate position, regardless of whether tabs or // spaces are used: @@ -161,7 +165,7 @@ function getErrorSource( } prefix = StringPrototypeSlice(prefix, 0, -1); // The last character is '^'. - exceptionLine = + const exceptionLine = `${originalSourcePathNoScheme}:${originalLine + 1}\n${line}\n${prefix}^\n\n`; return exceptionLine; } @@ -184,10 +188,7 @@ function getOriginalSource(payload, originalSourcePath) { source = readFileSync(originalSourcePathNoScheme, 'utf8'); } catch (err) { debug(err); - source = ''; } - } else { - source = ''; } return source; } diff --git a/src/node_errors.cc b/src/node_errors.cc index 63c6ea09d59152..a07620821c300d 100644 --- a/src/node_errors.cc +++ b/src/node_errors.cc @@ -105,7 +105,9 @@ static std::string GetErrorSource(Isolate* isolate, if (has_source_map_url && env != nullptr && env->source_maps_enabled()) { std::string source = GetSourceMapErrorSource( isolate, context, message, added_exception_line); - return *added_exception_line ? source : sourceline; + if (*added_exception_line) { + return source; + } } // Because of how node modules work, all scripts are wrapped with a diff --git a/test/fixtures/source-map/no-source.js b/test/fixtures/source-map/no-source.js new file mode 100644 index 00000000000000..da2c7ee5b39cba --- /dev/null +++ b/test/fixtures/source-map/no-source.js @@ -0,0 +1,9 @@ +function Throw() { + throw new Error('foo'); +} +Throw(); +// To recreate: +// +// npx tsc --outDir test/fixtures/source-map --sourceMap test/fixtures/source-map/no-source.ts +// rename the "source.[0]" to "file-not-exists.ts" +//# sourceMappingURL=no-source.js.map \ No newline at end of file diff --git a/test/fixtures/source-map/no-source.js.map b/test/fixtures/source-map/no-source.js.map new file mode 100644 index 00000000000000..d2c8238d4d0276 --- /dev/null +++ b/test/fixtures/source-map/no-source.js.map @@ -0,0 +1 @@ +{"version":3,"file":"no-source.js","sourceRoot":"","sources":["file-not-exists.ts"],"names":[],"mappings":"AAAA,SAAS,KAAK;IACZ,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;AACzB,CAAC;AAED,KAAK,EAAE,CAAC;AAER,eAAe;AACf,EAAE;AACF,8FAA8F;AAC9F,kDAAkD"} \ No newline at end of file diff --git a/test/fixtures/source-map/no-source.ts b/test/fixtures/source-map/no-source.ts new file mode 100644 index 00000000000000..399fc9556d9fbd --- /dev/null +++ b/test/fixtures/source-map/no-source.ts @@ -0,0 +1,10 @@ +function Throw() { + throw new Error('foo'); +} + +Throw(); + +// To recreate: +// +// npx tsc --outDir test/fixtures/source-map --sourceMap test/fixtures/source-map/no-source.ts +// rename the "source.[0]" to "file-not-exists.ts" diff --git a/test/message/source_map_no_source_file.js b/test/message/source_map_no_source_file.js new file mode 100644 index 00000000000000..971fa5e271550b --- /dev/null +++ b/test/message/source_map_no_source_file.js @@ -0,0 +1,6 @@ +// Flags: --enable-source-maps + +'use strict'; +require('../common'); + +require('../fixtures/source-map/no-source.js'); diff --git a/test/message/source_map_no_source_file.out b/test/message/source_map_no_source_file.out new file mode 100644 index 00000000000000..aa39992a81de74 --- /dev/null +++ b/test/message/source_map_no_source_file.out @@ -0,0 +1,17 @@ +*no-source.js:2 + throw new Error('foo'); + ^ + +Error: foo + at Throw (*file-not-exists.ts:2:9) + at Object. (*file-not-exists.ts:5:1) + at Module._compile (node:internal/modules/cjs/loader:*) + at Module._extensions..js (node:internal/modules/cjs/loader:*) + at Module.load (node:internal/modules/cjs/loader:*) + at Module._load (node:internal/modules/cjs/loader:*) + at Module.require (node:internal/modules/cjs/loader:*) + at require (node:internal/modules/cjs/helpers:*) + at Object. (*source_map_no_source_file.js:6:1) + at Module._compile (node:internal/modules/cjs/loader:*) + +Node.js *