- function handlePending( module ) {
- var j, job, hasErrors, m, stateChange, fromBaseModule;
-
- if ( registry[ module ].state === 'error' || registry[ module ].state === 'missing' ) {
- fromBaseModule = baseModules.indexOf( module ) !== -1;
- // If the current module failed, mark all dependent modules also as failed.
- // Iterate until steady-state to propagate the error state upwards in the
- // dependency tree.
- do {
- stateChange = false;
- for ( m in registry ) {
- if ( registry[ m ].state !== 'error' && registry[ m ].state !== 'missing' ) {
- // Always propagate errors from base modules to regular modules (implicit dependency).
- // Between base modules or regular modules, consider direct dependencies only.
- if (
- ( fromBaseModule && baseModules.indexOf( m ) === -1 ) ||
- anyFailed( registry[ m ].dependencies )
- ) {
- registry[ m ].state = 'error';
- stateChange = true;
+ function doPropagation() {
+ var errorModule, baseModuleError, module, i, failed, job,
+ didPropagate = true;
+
+ // Keep going until the last iteration performed no actions.
+ do {
+ didPropagate = false;
+
+ // Stage 1: Propagate failures
+ while ( errorModules.length ) {
+ errorModule = errorModules.shift();
+ baseModuleError = baseModules.indexOf( errorModule ) !== -1;
+ for ( module in registry ) {
+ if ( registry[ module ].state !== 'error' && registry[ module ].state !== 'missing' ) {
+ if ( baseModuleError && baseModules.indexOf( module ) === -1 ) {
+ // Propate error from base module to all regular (non-base) modules
+ registry[ module ].state = 'error';
+ didPropagate = true;
+ } else if ( registry[ module ].dependencies.indexOf( errorModule ) !== -1 ) {
+ // Propagate error from dependency to depending module
+ registry[ module ].state = 'error';
+ // .. and propagate it further
+ errorModules.push( module );
+ didPropagate = true;