mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-05-01 07:24:38 -07:00
fix(core): reduce default API timeout to 60s and enable retries for undici timeouts (#26191)
This commit is contained in:
@@ -209,7 +209,7 @@ describe('fetch utils', () => {
|
||||
expect(ProxyAgent).toHaveBeenCalledWith({
|
||||
uri: proxyUrl,
|
||||
headersTimeout: 45773134,
|
||||
bodyTimeout: 45773134,
|
||||
bodyTimeout: 300000,
|
||||
});
|
||||
expect(setGlobalDispatcher).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@@ -28,14 +28,15 @@ export class PrivateIpError extends Error {
|
||||
}
|
||||
}
|
||||
|
||||
let defaultTimeout = 300000; // 5 minutes
|
||||
let defaultHeadersTimeout = 60000; // 60 seconds
|
||||
const defaultBodyTimeout = 300000; // 5 minutes
|
||||
let currentProxy: string | undefined = undefined;
|
||||
|
||||
// Configure default global dispatcher with higher timeouts
|
||||
setGlobalDispatcher(
|
||||
new Agent({
|
||||
headersTimeout: defaultTimeout,
|
||||
bodyTimeout: defaultTimeout,
|
||||
headersTimeout: defaultHeadersTimeout,
|
||||
bodyTimeout: defaultBodyTimeout,
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -45,14 +46,15 @@ export function updateGlobalFetchTimeouts(timeoutMs: number) {
|
||||
`Invalid timeout value: ${timeoutMs}. Must be a positive finite number.`,
|
||||
);
|
||||
}
|
||||
defaultTimeout = timeoutMs;
|
||||
defaultHeadersTimeout = timeoutMs;
|
||||
// We keep body timeout high for LLM streaming responses
|
||||
if (currentProxy) {
|
||||
setGlobalProxy(currentProxy);
|
||||
} else {
|
||||
setGlobalDispatcher(
|
||||
new Agent({
|
||||
headersTimeout: defaultTimeout,
|
||||
bodyTimeout: defaultTimeout,
|
||||
headersTimeout: defaultHeadersTimeout,
|
||||
bodyTimeout: defaultBodyTimeout,
|
||||
}),
|
||||
);
|
||||
}
|
||||
@@ -214,8 +216,8 @@ export function setGlobalProxy(proxy: string) {
|
||||
setGlobalDispatcher(
|
||||
new ProxyAgent({
|
||||
uri: proxy,
|
||||
headersTimeout: defaultTimeout,
|
||||
bodyTimeout: defaultTimeout,
|
||||
headersTimeout: defaultHeadersTimeout,
|
||||
bodyTimeout: defaultBodyTimeout,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -451,6 +451,25 @@ describe('retryWithBackoff', () => {
|
||||
});
|
||||
await vi.runAllTimersAsync();
|
||||
await expect(promise).resolves.toBe('success');
|
||||
expect(mockFn).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
it('should retry on undici timeout error codes (UND_ERR_HEADERS_TIMEOUT)', async () => {
|
||||
const error = new Error('Headers timeout error');
|
||||
(error as any).code = 'UND_ERR_HEADERS_TIMEOUT';
|
||||
const mockFn = vi
|
||||
.fn()
|
||||
.mockRejectedValueOnce(error)
|
||||
.mockResolvedValue('success');
|
||||
|
||||
const promise = retryWithBackoff(mockFn, {
|
||||
retryFetchErrors: false,
|
||||
initialDelayMs: 1,
|
||||
maxDelayMs: 1,
|
||||
});
|
||||
await vi.runAllTimersAsync();
|
||||
await expect(promise).resolves.toBe('success');
|
||||
expect(mockFn).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
it('should retry on SSL error code (ERR_SSL_SSLV3_ALERT_BAD_RECORD_MAC)', async () => {
|
||||
|
||||
@@ -55,6 +55,9 @@ const RETRYABLE_NETWORK_CODES = [
|
||||
'ECONNREFUSED',
|
||||
'ERR_SSL_WRONG_VERSION_NUMBER',
|
||||
'EPROTO', // Generic protocol error (often SSL-related)
|
||||
'UND_ERR_HEADERS_TIMEOUT',
|
||||
'UND_ERR_BODY_TIMEOUT',
|
||||
'UND_ERR_CONNECT_TIMEOUT',
|
||||
];
|
||||
|
||||
// Node.js builds SSL error codes by prepending ERR_SSL_ to the uppercased
|
||||
|
||||
Reference in New Issue
Block a user