Skip to content

Commit 96427c4

Browse files
icecrasher321claude
andcommitted
fix(execution): keep the stream-error predicates safe for nullish rejections
isClientDisconnectError read error.name unguarded, so a stream that rejected with null or undefined would throw inside the catch and mask the original failure. Both predicates now take unknown and bail on non-object values; the executor test covers a nullish body-reader rejection. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
1 parent 623b3e9 commit 96427c4

2 files changed

Lines changed: 7 additions & 5 deletions

File tree

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ describe('workflow-execution-utils', () => {
129129
)
130130

131131
it.each([
132+
['a nullish rejection', null],
132133
['a client abort', new DOMException('Aborted', 'AbortError')],
133134
[
134135
'the run tool stop reason, which aborts with a plain string',

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

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { useCallback } from 'react'
22
import { createLogger } from '@sim/logger'
33
import { getErrorMessage } from '@sim/utils/errors'
4+
import { isRecordLike } from '@sim/utils/object'
45
import type { WorkflowStateContractInput } from '@/lib/api/contracts/workflows'
56
import { readSSEEvents } from '@/lib/core/utils/sse'
67
import type {
@@ -67,8 +68,8 @@ export class SSEStreamInterruptedError extends Error {
6768
* Detects errors caused by the browser killing a fetch (page refresh, navigation, tab close).
6869
* These should be treated as clean disconnects, not execution errors.
6970
*/
70-
function isClientDisconnectError(error: any): boolean {
71-
return error.name === 'AbortError'
71+
function isClientDisconnectError(error: unknown): boolean {
72+
return isRecordLike(error) && error.name === 'AbortError'
7273
}
7374

7475
/**
@@ -83,9 +84,9 @@ const TRANSPORT_FAILURE_MESSAGE_PATTERNS = [
8384
/load failed/,
8485
] as const
8586

86-
function isRecoverableStreamError(error: any): boolean {
87-
if (isClientDisconnectError(error)) return false
88-
const msg = (error.message ?? '').toLowerCase()
87+
function isRecoverableStreamError(error: unknown): boolean {
88+
if (!isRecordLike(error) || isClientDisconnectError(error)) return false
89+
const msg = typeof error.message === 'string' ? error.message.toLowerCase() : ''
8990
return TRANSPORT_FAILURE_MESSAGE_PATTERNS.some((pattern) => pattern.test(msg))
9091
}
9192

0 commit comments

Comments
 (0)