Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
pr comments
  • Loading branch information
waleedlatif1 committed Feb 11, 2026
commit 7865d9b09578506d166d850ca34c13360854492d
Original file line number Diff line number Diff line change
Expand Up @@ -82,21 +82,16 @@ function hasErrorInTree(span: TraceSpan): boolean {

/**
* Checks if a span or any of its descendants has an unhandled error.
* Container spans (loop, iteration, parallel) are skipped — only leaf
* block spans with errorHandled are considered. Used only for the root
* workflow span to match the actual workflow status.
* Spans with errorHandled: true (including containers that propagate it)
* are skipped. Used only for the root workflow span to match the actual
* workflow status.
*/
const CONTAINER_TYPES = new Set(['loop', 'loop-iteration', 'parallel', 'parallel-iteration'])
function hasUnhandledErrorInTree(span: TraceSpan): boolean {
const type = span.type?.toLowerCase() || ''
if (CONTAINER_TYPES.has(type)) {
return span.children ? span.children.some(hasUnhandledErrorInTree) : false
}
if (span.status === 'error' && !span.errorHandled) return true
if (span.children && span.children.length > 0) {
return span.children.some((child) => hasUnhandledErrorInTree(child))
}
if (span.toolCalls && span.toolCalls.length > 0) {
if (span.toolCalls && span.toolCalls.length > 0 && !span.errorHandled) {
return span.toolCalls.some((tc) => tc.error)
}
return false
Expand Down
6 changes: 0 additions & 6 deletions apps/sim/lib/logs/execution/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,14 +222,8 @@ export class ExecutionLogger implements IExecutionLoggerService {
// Determine if workflow failed by checking trace spans for unhandled errors
// Errors handled by error handler paths (errorHandled: true) don't count as workflow failures
// Use the override if provided (for cost-only fallback scenarios)
const containerTypes = ['loop', 'loop-iteration', 'parallel', 'parallel-iteration']
const hasErrors = traceSpans?.some((span: any) => {
const checkSpanForErrors = (s: any): boolean => {
if (containerTypes.includes(s.type?.toLowerCase() || '')) {
return s.children && Array.isArray(s.children)
? s.children.some(checkSpanForErrors)
: false
}
if (s.status === 'error' && !s.errorHandled) return true
if (s.children && Array.isArray(s.children)) {
return s.children.some(checkSpanForErrors)
Expand Down
6 changes: 0 additions & 6 deletions apps/sim/lib/logs/execution/logging-session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -299,14 +299,8 @@ export class LoggingSession {
'@/lib/core/telemetry'
)

const containerTypes = ['loop', 'loop-iteration', 'parallel', 'parallel-iteration']
const hasErrors = traceSpans.some((span: any) => {
const checkForErrors = (s: any): boolean => {
if (containerTypes.includes(s.type?.toLowerCase() || '')) {
return s.children && Array.isArray(s.children)
? s.children.some(checkForErrors)
: false
}
if (s.status === 'error' && !s.errorHandled) return true
if (s.children && Array.isArray(s.children)) {
return s.children.some(checkForErrors)
Expand Down
18 changes: 14 additions & 4 deletions apps/sim/lib/logs/execution/trace-spans/trace-spans.ts
Original file line number Diff line number Diff line change
Expand Up @@ -502,11 +502,7 @@ export function buildTraceSpans(result: ExecutionResult): {
}
addRelativeTimestamps(groupedRootSpans, earliestStart)

const containerTypes = new Set(['loop', 'loop-iteration', 'parallel', 'parallel-iteration'])
const checkForUnhandledErrors = (s: TraceSpan): boolean => {
if (containerTypes.has(s.type?.toLowerCase() || '')) {
return s.children ? s.children.some(checkForUnhandledErrors) : false
}
if (s.status === 'error' && !s.errorHandled) return true
return s.children ? s.children.some(checkForUnhandledErrors) : false
}
Expand Down Expand Up @@ -711,6 +707,8 @@ function groupIterationBlocks(spans: TraceSpan[]): TraceSpan[] {
const iterDuration = iterLatestEnd - iterEarliestStart

const hasErrors = spans.some((span) => span.status === 'error')
const allErrorsHandled =
hasErrors && spans.every((span) => span.status !== 'error' || span.errorHandled)

const iterationSpan: TraceSpan = {
id: `${containerId}-iteration-${iterationIndex}`,
Expand All @@ -720,6 +718,7 @@ function groupIterationBlocks(spans: TraceSpan[]): TraceSpan[] {
startTime: new Date(iterEarliestStart).toISOString(),
endTime: new Date(iterLatestEnd).toISOString(),
status: hasErrors ? 'error' : 'success',
...(allErrorsHandled && { errorHandled: true }),
children: spans.map((span) => ({
...span,
name: span.name.replace(/ \(iteration \d+\)$/, ''),
Expand All @@ -730,6 +729,9 @@ function groupIterationBlocks(spans: TraceSpan[]): TraceSpan[] {
})

const hasErrors = allIterationSpans.some((span) => span.status === 'error')
const allErrorsHandled =
hasErrors &&
iterationChildren.every((span) => span.status !== 'error' || span.errorHandled)
const parallelContainer: TraceSpan = {
id: `parallel-execution-${containerId}`,
name: containerName,
Expand All @@ -738,6 +740,7 @@ function groupIterationBlocks(spans: TraceSpan[]): TraceSpan[] {
startTime: new Date(earliestStart).toISOString(),
endTime: new Date(latestEnd).toISOString(),
status: hasErrors ? 'error' : 'success',
...(allErrorsHandled && { errorHandled: true }),
children: iterationChildren,
}

Expand All @@ -763,6 +766,8 @@ function groupIterationBlocks(spans: TraceSpan[]): TraceSpan[] {
const iterDuration = iterLatestEnd - iterEarliestStart

const hasErrors = spans.some((span) => span.status === 'error')
const allErrorsHandled =
hasErrors && spans.every((span) => span.status !== 'error' || span.errorHandled)

const iterationSpan: TraceSpan = {
id: `${containerId}-iteration-${iterationIndex}`,
Expand All @@ -772,6 +777,7 @@ function groupIterationBlocks(spans: TraceSpan[]): TraceSpan[] {
startTime: new Date(iterEarliestStart).toISOString(),
endTime: new Date(iterLatestEnd).toISOString(),
status: hasErrors ? 'error' : 'success',
...(allErrorsHandled && { errorHandled: true }),
children: spans.map((span) => ({
...span,
name: span.name.replace(/ \(iteration \d+\)$/, ''),
Expand All @@ -782,6 +788,9 @@ function groupIterationBlocks(spans: TraceSpan[]): TraceSpan[] {
})

const hasErrors = allIterationSpans.some((span) => span.status === 'error')
const allErrorsHandled =
hasErrors &&
iterationChildren.every((span) => span.status !== 'error' || span.errorHandled)
const loopContainer: TraceSpan = {
id: `loop-execution-${containerId}`,
name: containerName,
Expand All @@ -790,6 +799,7 @@ function groupIterationBlocks(spans: TraceSpan[]): TraceSpan[] {
startTime: new Date(earliestStart).toISOString(),
endTime: new Date(latestEnd).toISOString(),
status: hasErrors ? 'error' : 'success',
...(allErrorsHandled && { errorHandled: true }),
children: iterationChildren,
}

Expand Down