(
ctx: ExecutionContext,
node: DAGNode,
block: SerializedBlock
)
| 81 | } |
| 82 | |
| 83 | async execute( |
| 84 | ctx: ExecutionContext, |
| 85 | node: DAGNode, |
| 86 | block: SerializedBlock |
| 87 | ): Promise<NormalizedBlockOutput> { |
| 88 | const handler = this.findHandler(block) |
| 89 | if (!handler) { |
| 90 | throw buildBlockExecutionError({ |
| 91 | block, |
| 92 | context: ctx, |
| 93 | error: `No handler found for block type: ${block.metadata?.id ?? 'unknown'}`, |
| 94 | }) |
| 95 | } |
| 96 | |
| 97 | const blockType = block.metadata?.id ?? '' |
| 98 | const isSentinel = isSentinelBlockType(blockType) |
| 99 | |
| 100 | // Capture startedAt and startTime at the same synchronous instant so |
| 101 | // blockLog.startedAt and performance.now()-derived durationMs share a |
| 102 | // single reference point. Any executor work below counts toward this block. |
| 103 | const startedAt = new Date().toISOString() |
| 104 | const startTime = performance.now() |
| 105 | |
| 106 | let blockLog: BlockLog | undefined |
| 107 | let blockStartPromise: Promise<void> | undefined |
| 108 | if (!isSentinel) { |
| 109 | blockLog = this.createBlockLog(ctx, node.id, block, node, startedAt) |
| 110 | ctx.blockLogs.push(blockLog) |
| 111 | blockStartPromise = this.fireBlockStartCallback(ctx, node, block, blockLog.executionOrder) |
| 112 | await blockStartPromise |
| 113 | } |
| 114 | |
| 115 | let resolvedInputs: Record<string, any> = {} |
| 116 | let inputsForLog: Record<string, any> = {} |
| 117 | |
| 118 | const nodeMetadata = { |
| 119 | ...this.buildNodeMetadata(node), |
| 120 | executionOrder: blockLog?.executionOrder, |
| 121 | } |
| 122 | let cleanupSelfReference: (() => void) | undefined |
| 123 | |
| 124 | if (block.metadata?.id === BlockType.HUMAN_IN_THE_LOOP) { |
| 125 | cleanupSelfReference = this.preparePauseResumeSelfReference(ctx, node, block, nodeMetadata) |
| 126 | } |
| 127 | |
| 128 | try { |
| 129 | if (!isSentinel && blockType) { |
| 130 | await validateBlockType(ctx.userId, ctx.workspaceId, blockType, ctx) |
| 131 | } |
| 132 | |
| 133 | if (block.metadata?.id === BlockType.FUNCTION) { |
| 134 | const { |
| 135 | resolvedInputs: fnInputs, |
| 136 | displayInputs, |
| 137 | contextVariables, |
| 138 | } = await this.resolver.resolveInputsForFunctionBlock( |
| 139 | ctx, |
| 140 | node.id, |
nothing calls this directly
no test coverage detected