@@ -6,10 +6,15 @@ const {
66 ArrayPrototypeReduce,
77 FunctionPrototypeCall,
88 JSONStringify,
9+ Number,
910 ObjectSetPrototypeOf,
1011 Promise,
1112 PromisePrototypeThen,
13+ RegExpPrototypeExec,
1214 RegExpPrototypeSymbolReplace,
15+ StringPrototypeIndexOf,
16+ StringPrototypeSplit,
17+ StringPrototypeStartsWith,
1318 encodeURIComponent,
1419 hardenRegExp,
1520} = primordials ;
@@ -24,16 +29,21 @@ const { imported_cjs_symbol } = internalBinding('symbols');
2429
2530const assert = require ( 'internal/assert' ) ;
2631const {
27- ERR_REQUIRE_ASYNC_MODULE ,
28- ERR_REQUIRE_CYCLE_MODULE ,
29- ERR_REQUIRE_ESM ,
30- ERR_REQUIRE_ESM_RACE_CONDITION ,
31- ERR_UNKNOWN_MODULE_FORMAT ,
32- } = require ( 'internal/errors' ) . codes ;
32+ codes : {
33+ ERR_REQUIRE_ASYNC_MODULE ,
34+ ERR_REQUIRE_CYCLE_MODULE ,
35+ ERR_REQUIRE_ESM ,
36+ ERR_REQUIRE_ESM_RACE_CONDITION ,
37+ ERR_UNKNOWN_MODULE_FORMAT ,
38+ } ,
39+ setArrowMessage,
40+ } = require ( 'internal/errors' ) ;
3341const { getOptionValue } = require ( 'internal/options' ) ;
3442const { isURL, pathToFileURL } = require ( 'internal/url' ) ;
43+ const { readFileSync } = require ( 'fs' ) ;
3544const {
3645 getDeprecationWarningEmitter,
46+ getLazy,
3747 kEmptyObject,
3848} = require ( 'internal/util' ) ;
3949const {
@@ -78,6 +88,83 @@ let debug = require('internal/util/debuglog').debuglog('esm', (fn) => {
7888} ) ;
7989
8090const { isPromise } = require ( 'internal/util/types' ) ;
91+ const lazyGetErrorSourceMessage =
92+ getLazy ( ( ) => require ( 'internal/errors/error_source' ) . getErrorSourceMessage ) ;
93+
94+ function getOrCreateModuleJobWithStackTraceLimit ( loader , parentURL , request , limit ) {
95+ const originalLimit = Error . stackTraceLimit ;
96+ try {
97+ if ( originalLimit < limit ) {
98+ Error . stackTraceLimit = limit ;
99+ }
100+ return loader . getOrCreateModuleJob ( parentURL , request ) ;
101+ } finally {
102+ Error . stackTraceLimit = originalLimit ;
103+ }
104+ }
105+
106+ function decorateDynamicImportModuleNotFoundError ( error , parentURL , specifier ) {
107+ if ( error ?. code !== 'ERR_MODULE_NOT_FOUND' ||
108+ typeof parentURL !== 'string' ||
109+ ! StringPrototypeStartsWith ( parentURL , 'file://' ) ) {
110+ return ;
111+ }
112+
113+ let filename ;
114+ try {
115+ filename = urlToFilename ( parentURL ) ;
116+ } catch {
117+ return ;
118+ }
119+
120+ const stackLines = StringPrototypeSplit ( error . stack , '\n' ) ;
121+ let frame ;
122+ for ( let i = 0 ; i < stackLines . length ; i ++ ) {
123+ if ( StringPrototypeStartsWith ( stackLines [ i ] , ' at ' ) &&
124+ ( StringPrototypeIndexOf ( stackLines [ i ] , parentURL ) !== - 1 ||
125+ StringPrototypeIndexOf ( stackLines [ i ] , filename ) !== - 1 ) ) {
126+ frame = stackLines [ i ] ;
127+ break ;
128+ }
129+ }
130+
131+ const { 1 : line , 2 : col } =
132+ RegExpPrototypeExec ( / : ( \d + ) : ( \d + ) \) ? $ / , frame ) || [ ] ;
133+ if ( ! line || ! col ) {
134+ return ;
135+ }
136+
137+ let source ;
138+ try {
139+ source = readFileSync ( filename , 'utf8' ) ;
140+ } catch {
141+ return ;
142+ }
143+
144+ const sourceLine = StringPrototypeSplit ( source , '\n' , line ) [ line - 1 ] ;
145+ if ( sourceLine === undefined ) {
146+ return ;
147+ }
148+
149+ let column = StringPrototypeIndexOf ( sourceLine , specifier , col - 1 ) ;
150+ if ( column === - 1 ) {
151+ column = StringPrototypeIndexOf ( sourceLine , specifier ) ;
152+ }
153+ if ( column === - 1 ) {
154+ column = col - 1 ;
155+ }
156+
157+ const message = lazyGetErrorSourceMessage ( ) (
158+ filename ,
159+ Number ( line ) ,
160+ sourceLine ,
161+ column ,
162+ specifier . length ,
163+ ) ;
164+ if ( message !== undefined ) {
165+ setArrowMessage ( error , message ) ;
166+ }
167+ }
81168
82169/**
83170 * @typedef {import('./hooks.js').AsyncLoaderHookWorker } AsyncLoaderHookWorker
@@ -612,11 +699,16 @@ class ModuleLoader {
612699 const request = { specifier, phase, attributes : importAttributes , __proto__ : null } ;
613700 let moduleJob ;
614701 try {
615- moduleJob = await this . getOrCreateModuleJob ( parentURL , request ) ;
702+ const maybeModuleJob =
703+ typeof parentURL === 'string' && StringPrototypeStartsWith ( parentURL , 'file://' ) ?
704+ getOrCreateModuleJobWithStackTraceLimit ( this , parentURL , request , 100 ) :
705+ this . getOrCreateModuleJob ( parentURL , request ) ;
706+ moduleJob = await maybeModuleJob ;
616707 } catch ( e ) {
617708 if ( e ?. code === 'ERR_ASYNC_LOADER_REQUEST_NEVER_SETTLED' ) {
618709 return new Promise ( ( ) => { } ) ;
619710 }
711+ decorateDynamicImportModuleNotFoundError ( e , parentURL , specifier ) ;
620712 throw e ;
621713 }
622714 if ( phase === kSourcePhase ) {
0 commit comments