Skip to content

Commit 189c94a

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 3d9d9cb commit 189c94a

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
@@ -648,14 +648,41 @@ async function handleInternalRequest(
648648
// Check request body size before sending to detect potential size limit issues
649649
validateRequestBodySize(requestParams.body, requestId, toolId)
650650

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

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

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

0 commit comments

Comments
 (0)