Skip to content

Commit 5b4f74a

Browse files
icecrasher321claude
andcommitted
fix(execution): never classify the stream layer's own errors as transport drops
An ExecutionStreamHttpError or SSEEventHandlerError whose message happened to contain a browser transport phrase ("Failed to fetch workflow state") would have been re-wrapped as a stream interruption, losing the HTTP status and taking the recovery path for a run that never started. The predicate now excludes the stream layer's typed errors before looking at message text. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
1 parent 96427c4 commit 5b4f74a

2 files changed

Lines changed: 32 additions & 2 deletions

File tree

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/utils/workflow-execution-utils.test.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ import {
1414
} from '@/app/workspace/[workspaceId]/w/[workflowId]/utils/workflow-execution-utils'
1515
import type { BlockLog } from '@/executor/types'
1616
import {
17-
type ExecutionStreamHttpError,
17+
ExecutionStreamHttpError,
18+
SSEEventHandlerError,
1819
SSEStreamInterruptedError,
1920
} from '@/hooks/use-execution-stream'
2021
import { useExecutionStore } from '@/stores/execution'
@@ -131,6 +132,20 @@ describe('workflow-execution-utils', () => {
131132
it.each([
132133
['a nullish rejection', null],
133134
['a client abort', new DOMException('Aborted', 'AbortError')],
135+
[
136+
'an HTTP rejection whose message mentions a transport phrase',
137+
new ExecutionStreamHttpError('Failed to fetch workflow state', 500),
138+
],
139+
[
140+
'a handler failure whose message mentions a transport phrase',
141+
new SSEEventHandlerError(
142+
'network error while persisting console rows',
143+
'block:completed',
144+
3,
145+
'exec-server',
146+
new Error('persist failed')
147+
),
148+
],
134149
[
135150
'the run tool stop reason, which aborts with a plain string',
136151
'user_stop:cancelRunToolExecution',

apps/sim/hooks/use-execution-stream.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,23 @@ const TRANSPORT_FAILURE_MESSAGE_PATTERNS = [
8484
/load failed/,
8585
] as const
8686

87+
/**
88+
* Errors the stream layer raises itself carry their own meaning (an HTTP
89+
* rejection, a handler failure, an already classified drop), so their message
90+
* text must never be mistaken for a transport failure.
91+
*/
92+
function isStreamLayerError(error: unknown): boolean {
93+
return (
94+
error instanceof ExecutionStreamHttpError ||
95+
error instanceof SSEEventHandlerError ||
96+
error instanceof SSEStreamInterruptedError
97+
)
98+
}
99+
87100
function isRecoverableStreamError(error: unknown): boolean {
88-
if (!isRecordLike(error) || isClientDisconnectError(error)) return false
101+
if (!isRecordLike(error) || isClientDisconnectError(error) || isStreamLayerError(error)) {
102+
return false
103+
}
89104
const msg = typeof error.message === 'string' ? error.message.toLowerCase() : ''
90105
return TRANSPORT_FAILURE_MESSAGE_PATTERNS.some((pattern) => pattern.test(msg))
91106
}

0 commit comments

Comments
 (0)