@@ -1058,25 +1058,58 @@ export function useWorkflowExecution() {
10581058 endedAt,
10591059 } )
10601060
1061- // Update existing console entry (created in onBlockStarted) with error data
1062- updateConsole (
1063- data . blockId ,
1064- {
1061+ // Check if entry exists (created in onBlockStarted)
1062+ // For container blocks like loops/parallels that fail during initialization,
1063+ // onBlockStarted is never called, so we need to create the entry here
1064+ const existingEntries = useTerminalConsoleStore . getState ( ) . entries
1065+ const hasExistingEntry = existingEntries . some (
1066+ ( entry ) => entry . blockId === data . blockId && entry . executionId === executionId
1067+ )
1068+
1069+ if ( hasExistingEntry ) {
1070+ // Update existing console entry
1071+ updateConsole (
1072+ data . blockId ,
1073+ {
1074+ input : data . input || { } ,
1075+ replaceOutput : { } ,
1076+ success : false ,
1077+ error : data . error ,
1078+ durationMs : data . durationMs ,
1079+ startedAt,
1080+ endedAt,
1081+ isRunning : false ,
1082+ // Pass through iteration context for subflow grouping
1083+ iterationCurrent : data . iterationCurrent ,
1084+ iterationTotal : data . iterationTotal ,
1085+ iterationType : data . iterationType ,
1086+ } ,
1087+ executionId
1088+ )
1089+ } else {
1090+ // Create new console entry for blocks that failed before starting
1091+ // (e.g., loop/parallel blocks with invalid configuration)
1092+ addConsole ( {
10651093 input : data . input || { } ,
1066- replaceOutput : { } ,
1094+ output : { } ,
10671095 success : false ,
10681096 error : data . error ,
1069- durationMs : data . durationMs ,
1070- startedAt,
1071- endedAt,
1097+ durationMs : data . durationMs || 0 ,
1098+ startedAt : startedAt || new Date ( ) . toISOString ( ) ,
1099+ executionOrder : data . executionOrder ,
1100+ endedAt : endedAt || new Date ( ) . toISOString ( ) ,
1101+ workflowId : activeWorkflowId ,
1102+ blockId : data . blockId ,
1103+ executionId,
1104+ blockName : data . blockName || 'Unknown Block' ,
1105+ blockType : data . blockType || 'unknown' ,
10721106 isRunning : false ,
10731107 // Pass through iteration context for subflow grouping
10741108 iterationCurrent : data . iterationCurrent ,
10751109 iterationTotal : data . iterationTotal ,
10761110 iterationType : data . iterationType ,
1077- } ,
1078- executionId
1079- )
1111+ } )
1112+ }
10801113 } ,
10811114
10821115 onStreamChunk : ( data ) => {
@@ -1192,8 +1225,10 @@ export function useWorkflowExecution() {
11921225
11931226 // Only add workflow-level error entry for:
11941227 // 1. Pre-execution errors (validation) - no blocks ran
1195- // 2. Timeout errors - no block has the error
1228+ // 2. Workflow-level errors (timeout, etc.) - no block has the error
11961229 if ( isPreExecutionError || ! blockAlreadyHasError ) {
1230+ // Determine if this is a timeout error based on the error message
1231+ const isTimeout = data . error ?. toLowerCase ( ) . includes ( 'timed out' )
11971232 addConsole ( {
11981233 input : { } ,
11991234 output : { } ,
@@ -1204,9 +1239,17 @@ export function useWorkflowExecution() {
12041239 executionOrder : isPreExecutionError ? 0 : Number . MAX_SAFE_INTEGER ,
12051240 endedAt : new Date ( ) . toISOString ( ) ,
12061241 workflowId : activeWorkflowId ,
1207- blockId : isPreExecutionError ? 'validation' : 'timeout-error' ,
1242+ blockId : isPreExecutionError
1243+ ? 'validation'
1244+ : isTimeout
1245+ ? 'timeout-error'
1246+ : 'execution-error' ,
12081247 executionId,
1209- blockName : isPreExecutionError ? 'Workflow Validation' : 'Timeout Error' ,
1248+ blockName : isPreExecutionError
1249+ ? 'Workflow Validation'
1250+ : isTimeout
1251+ ? 'Timeout Error'
1252+ : 'Execution Error' ,
12101253 blockType : isPreExecutionError ? 'validation' : 'error' ,
12111254 } )
12121255 }
@@ -1786,8 +1829,10 @@ export function useWorkflowExecution() {
17861829 // Check if any block already has an error - don't duplicate block errors
17871830 const blockAlreadyHasError = accumulatedBlockLogs . some ( ( log ) => log . error )
17881831
1789- // Only add timeout error entry if no block has the error
1832+ // Only add execution error entry if no block has the error
17901833 if ( ! blockAlreadyHasError ) {
1834+ // Determine if this is a timeout error based on the error message
1835+ const isTimeout = data . error ?. toLowerCase ( ) . includes ( 'timed out' )
17911836 addConsole ( {
17921837 input : { } ,
17931838 output : { } ,
@@ -1798,16 +1843,33 @@ export function useWorkflowExecution() {
17981843 executionOrder : Number . MAX_SAFE_INTEGER ,
17991844 endedAt : new Date ( ) . toISOString ( ) ,
18001845 workflowId,
1801- blockId : 'timeout-error' ,
1846+ blockId : isTimeout ? 'timeout-error' : 'execution -error',
18021847 executionId,
1803- blockName : 'Timeout Error' ,
1848+ blockName : isTimeout ? 'Timeout Error' : 'Execution Error',
18041849 blockType : 'error' ,
18051850 } )
18061851 }
18071852 } ,
18081853
1809- onExecutionCancelled : ( ) => {
1854+ onExecutionCancelled : ( data ) => {
18101855 cancelRunningEntries ( workflowId )
1856+
1857+ // Add console entry for cancellation
1858+ addConsole ( {
1859+ input : { } ,
1860+ output : { } ,
1861+ success : false ,
1862+ error : 'Execution was cancelled' ,
1863+ durationMs : data ?. duration || 0 ,
1864+ startedAt : new Date ( Date . now ( ) - ( data ?. duration || 0 ) ) . toISOString ( ) ,
1865+ executionOrder : Number . MAX_SAFE_INTEGER ,
1866+ endedAt : new Date ( ) . toISOString ( ) ,
1867+ workflowId,
1868+ blockId : 'cancelled' ,
1869+ executionId,
1870+ blockName : 'Execution Cancelled' ,
1871+ blockType : 'cancelled' ,
1872+ } )
18111873 } ,
18121874 } ,
18131875 } )
0 commit comments