@@ -51,7 +51,7 @@ export class LoopOrchestrator {
5151 private edgeManager : EdgeManager | null = null
5252 ) { }
5353
54- initializeLoopScope ( ctx : ExecutionContext , loopId : string ) : LoopScope {
54+ async initializeLoopScope ( ctx : ExecutionContext , loopId : string ) : Promise < LoopScope > {
5555 const loopConfig = this . dag . loopConfigs . get ( loopId ) as SerializedLoop | undefined
5656 if ( ! loopConfig ) {
5757 throw new Error ( `Loop config not found: ${ loopId } ` )
@@ -76,7 +76,7 @@ export class LoopOrchestrator {
7676 )
7777 if ( iterationError ) {
7878 logger . error ( iterationError , { loopId, requestedIterations } )
79- this . addLoopErrorLog ( ctx , loopId , loopType , iterationError , {
79+ await this . addLoopErrorLog ( ctx , loopId , loopType , iterationError , {
8080 iterations : requestedIterations ,
8181 } )
8282 scope . maxIterations = 0
@@ -99,7 +99,7 @@ export class LoopOrchestrator {
9999 } catch ( error ) {
100100 const errorMessage = `ForEach loop resolution failed: ${ error instanceof Error ? error . message : String ( error ) } `
101101 logger . error ( errorMessage , { loopId, forEachItems : loopConfig . forEachItems } )
102- this . addLoopErrorLog ( ctx , loopId , loopType , errorMessage , {
102+ await this . addLoopErrorLog ( ctx , loopId , loopType , errorMessage , {
103103 forEachItems : loopConfig . forEachItems ,
104104 } )
105105 scope . items = [ ]
@@ -117,7 +117,7 @@ export class LoopOrchestrator {
117117 )
118118 if ( sizeError ) {
119119 logger . error ( sizeError , { loopId, collectionSize : items . length } )
120- this . addLoopErrorLog ( ctx , loopId , loopType , sizeError , {
120+ await this . addLoopErrorLog ( ctx , loopId , loopType , sizeError , {
121121 forEachItems : loopConfig . forEachItems ,
122122 collectionSize : items . length ,
123123 } )
@@ -155,7 +155,7 @@ export class LoopOrchestrator {
155155 )
156156 if ( iterationError ) {
157157 logger . error ( iterationError , { loopId, requestedIterations } )
158- this . addLoopErrorLog ( ctx , loopId , loopType , iterationError , {
158+ await this . addLoopErrorLog ( ctx , loopId , loopType , iterationError , {
159159 iterations : requestedIterations ,
160160 } )
161161 scope . maxIterations = 0
@@ -182,14 +182,14 @@ export class LoopOrchestrator {
182182 return scope
183183 }
184184
185- private addLoopErrorLog (
185+ private async addLoopErrorLog (
186186 ctx : ExecutionContext ,
187187 loopId : string ,
188188 loopType : string ,
189189 errorMessage : string ,
190190 inputData ?: any
191- ) : void {
192- addSubflowErrorLog (
191+ ) : Promise < void > {
192+ await addSubflowErrorLog (
193193 ctx ,
194194 loopId ,
195195 'loop' ,
@@ -238,7 +238,7 @@ export class LoopOrchestrator {
238238 }
239239 if ( isCancelled ) {
240240 logger . info ( 'Loop execution cancelled' , { loopId, iteration : scope . iteration } )
241- return this . createExitResult ( ctx , loopId , scope )
241+ return await this . createExitResult ( ctx , loopId , scope )
242242 }
243243
244244 const iterationResults : NormalizedBlockOutput [ ] = [ ]
@@ -253,7 +253,7 @@ export class LoopOrchestrator {
253253 scope . currentIterationOutputs . clear ( )
254254
255255 if ( ! ( await this . evaluateCondition ( ctx , scope , scope . iteration + 1 ) ) ) {
256- return this . createExitResult ( ctx , loopId , scope )
256+ return await this . createExitResult ( ctx , loopId , scope )
257257 }
258258
259259 scope . iteration ++
@@ -269,11 +269,11 @@ export class LoopOrchestrator {
269269 }
270270 }
271271
272- private createExitResult (
272+ private async createExitResult (
273273 ctx : ExecutionContext ,
274274 loopId : string ,
275275 scope : LoopScope
276- ) : LoopContinuationResult {
276+ ) : Promise < LoopContinuationResult > {
277277 const results = scope . allIterationOutputs
278278 const output = { results }
279279 this . state . setBlockOutput ( loopId , output , DEFAULTS . EXECUTION_TIME )
@@ -282,19 +282,26 @@ export class LoopOrchestrator {
282282 const now = new Date ( ) . toISOString ( )
283283 const iterationContext = buildContainerIterationContext ( ctx , loopId )
284284
285- this . contextExtensions . onBlockComplete (
286- loopId ,
287- 'Loop' ,
288- 'loop' ,
289- {
290- output,
291- executionTime : DEFAULTS . EXECUTION_TIME ,
292- startedAt : now ,
293- executionOrder : getNextExecutionOrder ( ctx ) ,
294- endedAt : now ,
295- } ,
296- iterationContext
297- )
285+ try {
286+ await this . contextExtensions . onBlockComplete (
287+ loopId ,
288+ 'Loop' ,
289+ 'loop' ,
290+ {
291+ output,
292+ executionTime : DEFAULTS . EXECUTION_TIME ,
293+ startedAt : now ,
294+ executionOrder : getNextExecutionOrder ( ctx ) ,
295+ endedAt : now ,
296+ } ,
297+ iterationContext
298+ )
299+ } catch ( error ) {
300+ logger . warn ( 'Loop completion callback failed' , {
301+ loopId,
302+ error : error instanceof Error ? error . message : String ( error ) ,
303+ } )
304+ }
298305 }
299306
300307 return {
@@ -597,7 +604,7 @@ export class LoopOrchestrator {
597604 if ( ! scope . items || scope . items . length === 0 ) {
598605 logger . info ( 'ForEach loop has empty collection, skipping loop body' , { loopId } )
599606 this . state . setBlockOutput ( loopId , { results : [ ] } , DEFAULTS . EXECUTION_TIME )
600- emitEmptySubflowEvents ( ctx , loopId , 'loop' , this . contextExtensions )
607+ await emitEmptySubflowEvents ( ctx , loopId , 'loop' , this . contextExtensions )
601608 return false
602609 }
603610 return true
@@ -607,7 +614,7 @@ export class LoopOrchestrator {
607614 if ( scope . maxIterations === 0 ) {
608615 logger . info ( 'For loop has 0 iterations, skipping loop body' , { loopId } )
609616 this . state . setBlockOutput ( loopId , { results : [ ] } , DEFAULTS . EXECUTION_TIME )
610- emitEmptySubflowEvents ( ctx , loopId , 'loop' , this . contextExtensions )
617+ await emitEmptySubflowEvents ( ctx , loopId , 'loop' , this . contextExtensions )
611618 return false
612619 }
613620 return true
@@ -621,7 +628,7 @@ export class LoopOrchestrator {
621628 if ( ! scope . condition ) {
622629 logger . warn ( 'No condition defined for while loop' , { loopId } )
623630 this . state . setBlockOutput ( loopId , { results : [ ] } , DEFAULTS . EXECUTION_TIME )
624- emitEmptySubflowEvents ( ctx , loopId , 'loop' , this . contextExtensions )
631+ await emitEmptySubflowEvents ( ctx , loopId , 'loop' , this . contextExtensions )
625632 return false
626633 }
627634
@@ -634,7 +641,7 @@ export class LoopOrchestrator {
634641
635642 if ( ! result ) {
636643 this . state . setBlockOutput ( loopId , { results : [ ] } , DEFAULTS . EXECUTION_TIME )
637- emitEmptySubflowEvents ( ctx , loopId , 'loop' , this . contextExtensions )
644+ await emitEmptySubflowEvents ( ctx , loopId , 'loop' , this . contextExtensions )
638645 }
639646
640647 return result
0 commit comments