@@ -11,7 +11,7 @@ export default RegisterLoader;
1111 * - loader.register support
1212 * - hookable higher-level resolve
1313 * - instantiate hook returning a ModuleNamespace or undefined for es module loading
14- * - loader error behaviour as in HTML and loader specs, clearing failed modules from registration cache synchronously
14+ * - loader error behaviour as in HTML and loader specs, caching load and eval errors separately
1515 * - build tracing support by providing a .trace=true and .loads object format
1616 */
1717
@@ -25,8 +25,10 @@ function RegisterLoader () {
2525 var deleted = registryDelete . call ( this , key ) ;
2626
2727 // also delete from register registry if linked
28- if ( records . hasOwnProperty ( key ) && ! records [ key ] . linkRecord )
28+ if ( records . hasOwnProperty ( key ) && ! records [ key ] . linkRecord ) {
2929 delete records [ key ] ;
30+ deleted = true ;
31+ }
3032
3133 return deleted ;
3234 } ;
@@ -74,6 +76,9 @@ function createLoadRecord (state, key, registration) {
7476 // for already-loaded modules by adding themselves to their importerSetters
7577 importerSetters : undefined ,
7678
79+ loadError : undefined ,
80+ evalError : undefined ,
81+
7782 // in-flight linking record
7883 linkRecord : {
7984 // promise for instantiated
@@ -96,9 +101,8 @@ function createLoadRecord (state, key, registration) {
96101 // indicates if the load and all its dependencies are instantiated and linked
97102 // but not yet executed
98103 // mostly just a performance shortpath to avoid rechecking the promises above
99- linked : false ,
104+ linked : false
100105
101- error : undefined
102106 // NB optimization and way of ensuring module objects in setters
103107 // indicates setters which should run pre-execution of that dependency
104108 // setters is then just for completely executed module objects
@@ -130,10 +134,6 @@ RegisterLoader.prototype[Loader.resolveInstantiate] = function (key, parentKey)
130134 return instantiateDeps ( loader , instantiated , instantiated . linkRecord , registry , state , [ instantiated ] )
131135 . then ( function ( ) {
132136 return ensureEvaluate ( loader , instantiated , instantiated . linkRecord , registry , state , undefined ) ;
133- } )
134- . catch ( function ( err ) {
135- clearLoadErrors ( loader , instantiated ) ;
136- throw err ;
137137 } ) ;
138138 } ) ;
139139} ;
@@ -243,7 +243,8 @@ function instantiate (loader, load, link, registry, state) {
243243 return load ;
244244 } )
245245 . catch ( function ( err ) {
246- throw link . error = addToError ( err , 'Instantiating ' + load . key ) ;
246+ load . linkRecord = undefined ;
247+ throw load . loadError = load . loadError || addToError ( err , 'Instantiating ' + load . key ) ;
247248 } ) ) ;
248249}
249250
@@ -402,6 +403,9 @@ function instantiateDeps (loader, load, link, registry, state, seen) {
402403 var depLoad = link . dependencyInstantiations [ i ] ;
403404 var depLink = depLoad . linkRecord ;
404405
406+ if ( depLoad . loadError )
407+ throw depLoad . loadError ;
408+
405409 if ( ! depLink || depLink . linked )
406410 continue ;
407411
@@ -426,51 +430,12 @@ function instantiateDeps (loader, load, link, registry, state, seen) {
426430 return load ;
427431 } )
428432 . catch ( function ( err ) {
429- err = addToError ( err , 'Loading ' + load . key ) ;
430-
431433 // throw up the instantiateDeps stack
432- // loads are then synchonously cleared at the top-level through the clearLoadErrors helper below
433- // this then ensures avoiding partially unloaded tree states
434- link . error = link . error || err ;
435-
436- throw err ;
434+ load . linkRecord = undefined ;
435+ throw load . loadError = load . loadError || addToError ( err , 'Loading ' + load . key ) ;
437436 } ) ;
438437}
439438
440- // clears an errored load and all its errored dependencies from the loads registry
441- function clearLoadErrors ( loader , load ) {
442- var state = loader [ REGISTER_INTERNAL ] ;
443-
444- // clear from loads
445- if ( state . records [ load . key ] === load )
446- delete state . records [ load . key ] ;
447-
448- var link = load . linkRecord ;
449-
450- if ( ! link )
451- return ;
452-
453- if ( link . dependencyInstantiations )
454- link . dependencyInstantiations . forEach ( function ( depLoad , index ) {
455- if ( ! depLoad || depLoad instanceof ModuleNamespace )
456- return ;
457-
458- if ( depLoad . linkRecord ) {
459- if ( depLoad . linkRecord . error ) {
460- // provides a circular reference check
461- if ( state . records [ depLoad . key ] === depLoad )
462- clearLoadErrors ( loader , depLoad ) ;
463- }
464-
465- // unregister setters for es dependency load records that will remain
466- if ( link . setters && depLoad . importerSetters ) {
467- var setterIndex = depLoad . importerSetters . indexOf ( link . setters [ index ] ) ;
468- depLoad . importerSetters . splice ( setterIndex , 1 ) ;
469- }
470- }
471- } ) ;
472- }
473-
474439/*
475440 * System.register
476441 */
@@ -530,19 +495,17 @@ function ensureEvaluate (loader, load, link, registry, state, seen) {
530495 if ( load . module )
531496 return load . module ;
532497
533- if ( link . error )
534- throw link . error ;
498+ if ( load . evalError )
499+ throw load . evalError ;
535500
536501 if ( seen && seen . indexOf ( load ) !== - 1 )
537502 return load . linkRecord . moduleObj ;
538503
539504 // for ES loads we always run ensureEvaluate on top-level, so empty seen is passed regardless
540505 // for dynamic loads, we pass seen if also dynamic
541506 var err = doEvaluate ( loader , load , link , registry , state , link . setters ? [ ] : seen || [ ] ) ;
542- if ( err ) {
543- clearLoadErrors ( loader , load ) ;
507+ if ( err )
544508 throw err ;
545- }
546509
547510 return load . module ;
548511}
@@ -587,16 +550,19 @@ function doEvaluate (loader, load, link, registry, state, seen) {
587550 // custom Module returned from instantiate
588551 depLink = depLoad . linkRecord ;
589552 if ( depLink && seen . indexOf ( depLoad ) === - 1 ) {
590- if ( depLink . error )
591- err = depLink . error ;
553+ if ( depLoad . evalError )
554+ err = depLoad . evalError ;
592555 else
593556 // dynamic / declarative boundaries clear the "seen" list
594557 // we just let cross format circular throw as would happen in real implementations
595558 err = doEvaluate ( loader , depLoad , depLink , registry , state , depLink . setters ? seen : [ ] ) ;
596559 }
597560
598- if ( err )
599- return link . error = addToError ( err , 'Evaluating ' + load . key ) ;
561+ if ( err ) {
562+ load . linkRecord = undefined ;
563+ load . evalError = addToError ( err , 'Evaluating ' + load . key ) ;
564+ return load . evalError ;
565+ }
600566 }
601567 }
602568
@@ -647,8 +613,11 @@ function doEvaluate (loader, load, link, registry, state, seen) {
647613 }
648614 }
649615
616+ // dispose link record
617+ load . linkRecord = undefined ;
618+
650619 if ( err )
651- return link . error = addToError ( err , 'Evaluating ' + load . key ) ;
620+ return load . evalError = addToError ( err , 'Evaluating ' + load . key ) ;
652621
653622 registry [ load . key ] = load . module = new ModuleNamespace ( link . moduleObj ) ;
654623
@@ -661,9 +630,6 @@ function doEvaluate (loader, load, link, registry, state, seen) {
661630 load . importerSetters [ i ] ( load . module ) ;
662631 load . importerSetters = undefined ;
663632 }
664-
665- // dispose link record
666- load . linkRecord = undefined ;
667633}
668634
669635// {} is the closest we can get to call(undefined)
0 commit comments