@@ -16,8 +16,12 @@ import {
1616} from '@/lib/workflows/triggers/triggers'
1717import { useCurrentWorkflow } from '@/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-current-workflow'
1818import {
19+ addHttpErrorConsoleEntry ,
1920 type BlockEventHandlerConfig ,
2021 createBlockEventHandlers ,
22+ addExecutionErrorConsoleEntry as sharedAddExecutionErrorConsoleEntry ,
23+ handleExecutionCancelledConsole as sharedHandleExecutionCancelledConsole ,
24+ handleExecutionErrorConsole as sharedHandleExecutionErrorConsole ,
2125} from '@/app/workspace/[workspaceId]/w/[workflowId]/utils/workflow-execution-utils'
2226import { getBlock } from '@/blocks'
2327import type { SerializableExecutionState } from '@/executor/execution/types'
@@ -159,22 +163,7 @@ export function useWorkflowExecution() {
159163 setActiveBlocks ,
160164 ] )
161165
162- /**
163- * Builds timing fields for execution-level console entries.
164- */
165- const buildExecutionTiming = useCallback ( ( durationMs ?: number ) => {
166- const normalizedDuration = durationMs || 0
167- return {
168- durationMs : normalizedDuration ,
169- startedAt : new Date ( Date . now ( ) - normalizedDuration ) . toISOString ( ) ,
170- endedAt : new Date ( ) . toISOString ( ) ,
171- }
172- } , [ ] )
173-
174- /**
175- * Adds an execution-level error entry to the console when appropriate.
176- */
177- const addExecutionErrorConsoleEntry = useCallback (
166+ const handleExecutionErrorConsole = useCallback (
178167 ( params : {
179168 workflowId ?: string
180169 executionId ?: string
@@ -184,102 +173,23 @@ export function useWorkflowExecution() {
184173 isPreExecutionError ?: boolean
185174 } ) => {
186175 if ( ! params . workflowId ) return
187-
188- const hasBlockError = params . blockLogs . some ( ( log ) => log . error )
189- const isPreExecutionError = params . isPreExecutionError ?? false
190- if ( ! isPreExecutionError && hasBlockError ) {
191- return
192- }
193-
194- const errorMessage = params . error || 'Execution failed'
195- const isTimeout = errorMessage . toLowerCase ( ) . includes ( 'timed out' )
196- const timing = buildExecutionTiming ( params . durationMs )
197-
198- addConsole ( {
199- input : { } ,
200- output : { } ,
201- success : false ,
202- error : errorMessage ,
203- durationMs : timing . durationMs ,
204- startedAt : timing . startedAt ,
205- executionOrder : isPreExecutionError ? 0 : Number . MAX_SAFE_INTEGER ,
206- endedAt : timing . endedAt ,
176+ sharedHandleExecutionErrorConsole ( addConsole , cancelRunningEntries , {
177+ ...params ,
207178 workflowId : params . workflowId ,
208- blockId : isPreExecutionError
209- ? 'validation'
210- : isTimeout
211- ? 'timeout-error'
212- : 'execution-error' ,
213- executionId : params . executionId ,
214- blockName : isPreExecutionError
215- ? 'Workflow Validation'
216- : isTimeout
217- ? 'Timeout Error'
218- : 'Execution Error' ,
219- blockType : isPreExecutionError ? 'validation' : 'error' ,
220179 } )
221180 } ,
222- [ addConsole , buildExecutionTiming ]
181+ [ addConsole , cancelRunningEntries ]
223182 )
224183
225- /**
226- * Adds an execution-level cancellation entry to the console.
227- */
228- const addExecutionCancelledConsoleEntry = useCallback (
184+ const handleExecutionCancelledConsole = useCallback (
229185 ( params : { workflowId ?: string ; executionId ?: string ; durationMs ?: number } ) => {
230186 if ( ! params . workflowId ) return
231-
232- const timing = buildExecutionTiming ( params . durationMs )
233- addConsole ( {
234- input : { } ,
235- output : { } ,
236- success : false ,
237- error : 'Execution was cancelled' ,
238- durationMs : timing . durationMs ,
239- startedAt : timing . startedAt ,
240- executionOrder : Number . MAX_SAFE_INTEGER ,
241- endedAt : timing . endedAt ,
187+ sharedHandleExecutionCancelledConsole ( addConsole , cancelRunningEntries , {
188+ ...params ,
242189 workflowId : params . workflowId ,
243- blockId : 'cancelled' ,
244- executionId : params . executionId ,
245- blockName : 'Execution Cancelled' ,
246- blockType : 'cancelled' ,
247190 } )
248191 } ,
249- [ addConsole , buildExecutionTiming ]
250- )
251-
252- /**
253- * Handles workflow-level execution errors for console output.
254- */
255- const handleExecutionErrorConsole = useCallback (
256- ( params : {
257- workflowId ?: string
258- executionId ?: string
259- error ?: string
260- durationMs ?: number
261- blockLogs : BlockLog [ ]
262- isPreExecutionError ?: boolean
263- } ) => {
264- if ( params . workflowId ) {
265- cancelRunningEntries ( params . workflowId )
266- }
267- addExecutionErrorConsoleEntry ( params )
268- } ,
269- [ addExecutionErrorConsoleEntry , cancelRunningEntries ]
270- )
271-
272- /**
273- * Handles workflow-level execution cancellations for console output.
274- */
275- const handleExecutionCancelledConsole = useCallback (
276- ( params : { workflowId ?: string ; executionId ?: string ; durationMs ?: number } ) => {
277- if ( params . workflowId ) {
278- cancelRunningEntries ( params . workflowId )
279- }
280- addExecutionCancelledConsoleEntry ( params )
281- } ,
282- [ addExecutionCancelledConsoleEntry , cancelRunningEntries ]
192+ [ addConsole , cancelRunningEntries ]
283193 )
284194
285195 const buildBlockEventHandlers = useCallback (
@@ -1319,31 +1229,42 @@ export function useWorkflowExecution() {
13191229 } else {
13201230 if ( ! executor ) {
13211231 try {
1322- let blockId = 'serialization'
1323- let blockName = 'Workflow'
1324- let blockType = 'serializer'
1325- if ( error instanceof WorkflowValidationError ) {
1326- blockId = error . blockId || blockId
1327- blockName = error . blockName || blockName
1328- blockType = error . blockType || blockType
1232+ const httpStatus =
1233+ isRecord ( error ) && typeof error . httpStatus === 'number' ? error . httpStatus : undefined
1234+ const storeAddConsole = useTerminalConsoleStore . getState ( ) . addConsole
1235+
1236+ if ( httpStatus && activeWorkflowId ) {
1237+ addHttpErrorConsoleEntry ( storeAddConsole , {
1238+ workflowId : activeWorkflowId ,
1239+ executionId : options ?. executionId ,
1240+ error : normalizedMessage ,
1241+ httpStatus,
1242+ } )
1243+ } else if ( error instanceof WorkflowValidationError ) {
1244+ storeAddConsole ( {
1245+ input : { } ,
1246+ output : { } ,
1247+ success : false ,
1248+ error : normalizedMessage ,
1249+ durationMs : 0 ,
1250+ startedAt : new Date ( ) . toISOString ( ) ,
1251+ executionOrder : Number . MAX_SAFE_INTEGER ,
1252+ endedAt : new Date ( ) . toISOString ( ) ,
1253+ workflowId : activeWorkflowId || '' ,
1254+ blockId : error . blockId || 'serialization' ,
1255+ executionId : options ?. executionId ,
1256+ blockName : error . blockName || 'Workflow' ,
1257+ blockType : error . blockType || 'serializer' ,
1258+ } )
1259+ } else {
1260+ sharedAddExecutionErrorConsoleEntry ( storeAddConsole , {
1261+ workflowId : activeWorkflowId || '' ,
1262+ executionId : options ?. executionId ,
1263+ error : normalizedMessage ,
1264+ blockLogs : [ ] ,
1265+ isPreExecutionError : true ,
1266+ } )
13291267 }
1330-
1331- // Use MAX_SAFE_INTEGER so execution errors appear at the end of the log
1332- useTerminalConsoleStore . getState ( ) . addConsole ( {
1333- input : { } ,
1334- output : { } ,
1335- success : false ,
1336- error : normalizedMessage ,
1337- durationMs : 0 ,
1338- startedAt : new Date ( ) . toISOString ( ) ,
1339- executionOrder : Number . MAX_SAFE_INTEGER ,
1340- endedAt : new Date ( ) . toISOString ( ) ,
1341- workflowId : activeWorkflowId || '' ,
1342- blockId,
1343- executionId : options ?. executionId ,
1344- blockName,
1345- blockType,
1346- } )
13471268 } catch { }
13481269 }
13491270
@@ -1681,8 +1602,8 @@ export function useWorkflowExecution() {
16811602 accumulatedBlockLogs,
16821603 accumulatedBlockStates,
16831604 executedBlockIds,
1684- consoleMode : 'add ' ,
1685- includeStartConsoleEntry : false ,
1605+ consoleMode : 'update ' ,
1606+ includeStartConsoleEntry : true ,
16861607 } )
16871608
16881609 await executionStream . executeFromBlock ( {
0 commit comments