Skip to content

Commit 19e6c6c

Browse files
committed
fix(connectors): retry transient DNS failures in secureFetchWithRetry
secureFetchWithValidation throws a validation error before the request when a hostname temporarily fails to resolve. Classify that transient DNS failure as retryable so secureFetchWithRetry mirrors the old fetchWithRetry network-retry behavior, while keeping the deterministic blocked-IP SSRF rejection non-retryable.
1 parent 46401b8 commit 19e6c6c

2 files changed

Lines changed: 12 additions & 0 deletions

File tree

apps/sim/lib/knowledge/documents/utils.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,10 @@ describe('isRetryableError', () => {
132132
it.concurrent('returns true for "service unavailable" in message', () => {
133133
expect(isRetryableError(new Error('The service unavailable right now'))).toBe(true)
134134
})
135+
136+
it.concurrent('returns true for a transient DNS resolution failure', () => {
137+
expect(isRetryableError(new Error('url hostname could not be resolved'))).toBe(true)
138+
})
135139
})
136140

137141
describe('case insensitivity', () => {
@@ -178,6 +182,10 @@ describe('isRetryableError', () => {
178182
it.concurrent('returns false for plain object with non-retryable status and no message', () => {
179183
expect(isRetryableError({ status: 500 })).toBe(false)
180184
})
185+
186+
it.concurrent('returns false for the deterministic blocked-IP SSRF rejection', () => {
187+
expect(isRetryableError(new Error('url resolves to a blocked IP address'))).toBe(false)
188+
})
181189
})
182190
})
183191

apps/sim/lib/knowledge/documents/utils.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ export function isRetryableError(error: unknown): boolean {
6767
'enetunreach',
6868
'socket hang up',
6969
'network error',
70+
// Transient DNS resolution failure surfaced by secureFetchWithValidation
71+
// before the request is made. The deterministic "resolves to a blocked IP
72+
// address" security rejection is a distinct message and stays non-retryable.
73+
'could not be resolved',
7074
]
7175

7276
if (networkKeywords.some((keyword) => lowerMessage.includes(keyword))) {

0 commit comments

Comments
 (0)