Skip to content

Commit c23eb1c

Browse files
committed
feat(http): add configurable timeout for API block requests
Adds timeout parameter to HTTP request tool and API block: - Default timeout: 120000ms (2 minutes) - Max timeout: 600000ms (10 minutes) - User-friendly error message on timeout This allows users to configure longer timeouts for slow API endpoints. Fixes #2242
1 parent fe73039 commit c23eb1c

File tree

4 files changed

+46
-3
lines changed

4 files changed

+46
-3
lines changed

apps/sim/blocks/blocks/api.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,14 @@ Example:
8080
generationType: 'json-object',
8181
},
8282
},
83+
{
84+
id: 'timeout',
85+
title: 'Timeout (ms)',
86+
type: 'short-input',
87+
placeholder: '120000',
88+
description:
89+
'Request timeout in milliseconds. Default: 120000ms (2 min). Max: 600000ms (10 min).',
90+
},
8391
],
8492
tools: {
8593
access: ['http_request'],
@@ -90,6 +98,7 @@ Example:
9098
headers: { type: 'json', description: 'Request headers' },
9199
body: { type: 'json', description: 'Request body data' },
92100
params: { type: 'json', description: 'URL query parameters' },
101+
timeout: { type: 'number', description: 'Request timeout in milliseconds' },
93102
},
94103
outputs: {
95104
data: { type: 'json', description: 'API response data (JSON, text, or other formats)' },

apps/sim/tools/http/request.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ export const requestTool: ToolConfig<RequestParams, RequestResponse> = {
4040
type: 'object',
4141
description: 'Form data to send (will set appropriate Content-Type)',
4242
},
43+
timeout: {
44+
type: 'number',
45+
default: 120000,
46+
description:
47+
'Request timeout in milliseconds. Default is 120000ms (2 minutes). Max is 600000ms (10 minutes).',
48+
},
4349
},
4450

4551
request: {

apps/sim/tools/http/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export interface RequestParams {
88
params?: TableRow[]
99
pathParams?: Record<string, string>
1010
formData?: Record<string, string | Blob>
11+
timeout?: number
1112
}
1213

1314
export interface RequestResponse extends ToolResponse {

apps/sim/tools/index.ts

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -650,14 +650,41 @@ async function handleInternalRequest(
650650
// Check request body size before sending to detect potential size limit issues
651651
validateRequestBodySize(requestParams.body, requestId, toolId)
652652

653-
// Prepare request options
654-
const requestOptions = {
653+
// Determine timeout: use params.timeout if provided, otherwise default to 120000ms (2 min)
654+
// Max timeout is 600000ms (10 minutes) to prevent indefinite waits
655+
const DEFAULT_TIMEOUT_MS = 120000
656+
const MAX_TIMEOUT_MS = 600000
657+
let timeoutMs = DEFAULT_TIMEOUT_MS
658+
if (typeof params.timeout === 'number' && params.timeout > 0) {
659+
timeoutMs = Math.min(params.timeout, MAX_TIMEOUT_MS)
660+
} else if (typeof params.timeout === 'string') {
661+
const parsed = Number.parseInt(params.timeout, 10)
662+
if (!Number.isNaN(parsed) && parsed > 0) {
663+
timeoutMs = Math.min(parsed, MAX_TIMEOUT_MS)
664+
}
665+
}
666+
667+
// Prepare request options with timeout signal
668+
const requestOptions: RequestInit = {
655669
method: requestParams.method,
656670
headers: headers,
657671
body: requestParams.body,
672+
signal: AbortSignal.timeout(timeoutMs),
658673
}
659674

660-
const response = await fetch(fullUrl, requestOptions)
675+
let response: Response
676+
try {
677+
response = await fetch(fullUrl, requestOptions)
678+
} catch (fetchError) {
679+
// Handle timeout error specifically
680+
if (fetchError instanceof Error && fetchError.name === 'TimeoutError') {
681+
logger.error(`[${requestId}] Request timed out for ${toolId} after ${timeoutMs}ms`)
682+
throw new Error(
683+
`Request timed out after ${timeoutMs}ms. Consider increasing the timeout value.`
684+
)
685+
}
686+
throw fetchError
687+
}
661688

662689
// For non-OK responses, attempt JSON first; if parsing fails, fall back to text
663690
if (!response.ok) {

0 commit comments

Comments
 (0)