Skip to content

Commit a5ceba9

Browse files
heiskrCopilot
andauthored
Add 4s timeout to AI search proxy upstream requests (#60366)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent f02d19d commit a5ceba9

File tree

1 file changed

+17
-3
lines changed

1 file changed

+17
-3
lines changed

src/search/lib/ai-search-proxy.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ import { getCSECopilotSource } from '@/search/lib/helpers/cse-copilot-docs-versi
66
import type { ExtendedRequest } from '@/types'
77
import { handleExternalSearchAnalytics } from '@/search/lib/helpers/external-search-analytics'
88

9+
// Maximum time (ms) to wait for the initial response from the upstream
10+
// AI search service. Streaming may take longer once the connection is
11+
// established, but the connect + first-byte must complete within this window.
12+
const AI_SEARCH_TIMEOUT_MS = 4_000
13+
914
export const aiSearchProxy = async (req: ExtendedRequest, res: Response) => {
1015
const { query, version } = req.body ?? {}
1116

@@ -71,6 +76,7 @@ export const aiSearchProxy = async (req: ExtendedRequest, res: Response) => {
7176
},
7277
},
7378
{
79+
timeout: AI_SEARCH_TIMEOUT_MS,
7480
throwHttpErrors: false,
7581
},
7682
)
@@ -143,9 +149,17 @@ export const aiSearchProxy = async (req: ExtendedRequest, res: Response) => {
143149
}
144150
}
145151
} catch (error) {
146-
statsd.increment('ai-search.route_error', 1, diagnosticTags)
147-
console.error('Error posting /answers to cse-copilot:', error)
148-
res.status(500).json({ errors: [{ message: 'Internal server error' }] })
152+
const isTimeout = error instanceof Error && error.message.includes('timed out')
153+
154+
if (isTimeout) {
155+
statsd.increment('ai-search.timeout', 1, diagnosticTags)
156+
console.error(`AI search request timed out after ${AI_SEARCH_TIMEOUT_MS}ms`)
157+
res.status(504).json({ errors: [{ message: 'Upstream request timed out' }] })
158+
} else {
159+
statsd.increment('ai-search.route_error', 1, diagnosticTags)
160+
console.error('Error posting /answers to cse-copilot:', error)
161+
res.status(500).json({ errors: [{ message: 'Internal server error' }] })
162+
}
149163
} finally {
150164
// Ensure reader lock is always released
151165
if (reader) {

0 commit comments

Comments
 (0)