@@ -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 ;
@@ -30,8 +35,13 @@ const {
3035 ERR_REQUIRE_ESM_RACE_CONDITION ,
3136 ERR_UNKNOWN_MODULE_FORMAT ,
3237} = require ( 'internal/errors' ) . codes ;
38+ const { setArrowMessage } = require ( 'internal/errors' ) ;
39+ const {
40+ getErrorSourceMessage,
41+ } = require ( 'internal/errors/error_source' ) ;
3342const { getOptionValue } = require ( 'internal/options' ) ;
3443const { isURL, pathToFileURL } = require ( 'internal/url' ) ;
44+ const { readFileSync } = require ( 'fs' ) ;
3545const {
3646 getDeprecationWarningEmitter,
3747 kEmptyObject,
@@ -79,6 +89,81 @@ let debug = require('internal/util/debuglog').debuglog('esm', (fn) => {
7989
8090const { isPromise } = require ( 'internal/util/types' ) ;
8191
92+ function getOrCreateModuleJobWithStackTraceLimit ( loader , parentURL , request , limit ) {
93+ const originalLimit = Error . stackTraceLimit ;
94+ try {
95+ if ( originalLimit < limit ) {
96+ Error . stackTraceLimit = limit ;
97+ }
98+ return loader . getOrCreateModuleJob ( parentURL , request ) ;
99+ } finally {
100+ Error . stackTraceLimit = originalLimit ;
101+ }
102+ }
103+
104+ function decorateDynamicImportModuleNotFoundError ( error , parentURL , specifier ) {
105+ if ( error ?. code !== 'ERR_MODULE_NOT_FOUND' ||
106+ typeof parentURL !== 'string' ||
107+ ! StringPrototypeStartsWith ( parentURL , 'file://' ) ) {
108+ return ;
109+ }
110+
111+ let filename ;
112+ try {
113+ filename = urlToFilename ( parentURL ) ;
114+ } catch {
115+ return ;
116+ }
117+
118+ const stackLines = StringPrototypeSplit ( error . stack , '\n' ) ;
119+ let frame ;
120+ for ( let i = 0 ; i < stackLines . length ; i ++ ) {
121+ if ( StringPrototypeStartsWith ( stackLines [ i ] , ' at ' ) &&
122+ ( StringPrototypeIndexOf ( stackLines [ i ] , parentURL ) !== - 1 ||
123+ StringPrototypeIndexOf ( stackLines [ i ] , filename ) !== - 1 ) ) {
124+ frame = stackLines [ i ] ;
125+ break ;
126+ }
127+ }
128+
129+ const { 1 : line , 2 : col } =
130+ RegExpPrototypeExec ( / : ( \d + ) : ( \d + ) \) ? $ / , frame ) || [ ] ;
131+ if ( ! line || ! col ) {
132+ return ;
133+ }
134+
135+ let source ;
136+ try {
137+ source = readFileSync ( filename , 'utf8' ) ;
138+ } catch {
139+ return ;
140+ }
141+
142+ const sourceLine = StringPrototypeSplit ( source , '\n' , line ) [ line - 1 ] ;
143+ if ( sourceLine === undefined ) {
144+ return ;
145+ }
146+
147+ let column = StringPrototypeIndexOf ( sourceLine , specifier , col - 1 ) ;
148+ if ( column === - 1 ) {
149+ column = StringPrototypeIndexOf ( sourceLine , specifier ) ;
150+ }
151+ if ( column === - 1 ) {
152+ column = col - 1 ;
153+ }
154+
155+ const message = getErrorSourceMessage (
156+ filename ,
157+ Number ( line ) ,
158+ sourceLine ,
159+ column ,
160+ specifier . length ,
161+ ) ;
162+ if ( message !== undefined ) {
163+ setArrowMessage ( error , message ) ;
164+ }
165+ }
166+
82167/**
83168 * @typedef {import('./hooks.js').AsyncLoaderHookWorker } AsyncLoaderHookWorker
84169 * @typedef {import('./module_job.js').ModuleJobBase } ModuleJobBase
@@ -612,11 +697,16 @@ class ModuleLoader {
612697 const request = { specifier, phase, attributes : importAttributes , __proto__ : null } ;
613698 let moduleJob ;
614699 try {
615- moduleJob = await this . getOrCreateModuleJob ( parentURL , request ) ;
700+ const maybeModuleJob =
701+ typeof parentURL === 'string' && StringPrototypeStartsWith ( parentURL , 'file://' ) ?
702+ getOrCreateModuleJobWithStackTraceLimit ( this , parentURL , request , 100 ) :
703+ this . getOrCreateModuleJob ( parentURL , request ) ;
704+ moduleJob = await maybeModuleJob ;
616705 } catch ( e ) {
617706 if ( e ?. code === 'ERR_ASYNC_LOADER_REQUEST_NEVER_SETTLED' ) {
618707 return new Promise ( ( ) => { } ) ;
619708 }
709+ decorateDynamicImportModuleNotFoundError ( e , parentURL , specifier ) ;
620710 throw e ;
621711 }
622712 if ( phase === kSourcePhase ) {
0 commit comments