mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-21 10:34:35 -07:00
Co-authored-by: Aashir Javed <Aaxhirrr@users.noreply.github.com> Co-authored-by: Dev Randalpura <devrandalpura@google.com>
This commit is contained in:
@@ -634,6 +634,58 @@ describe('retryWithBackoff', () => {
|
||||
);
|
||||
expect(mockFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should not emit onRetry when aborted before catch retry handling', async () => {
|
||||
const abortController = new AbortController();
|
||||
const onRetry = vi.fn();
|
||||
const mockFn = vi.fn().mockImplementation(async () => {
|
||||
const error = new Error('Server error') as HttpError;
|
||||
error.status = 500;
|
||||
abortController.abort();
|
||||
throw error;
|
||||
});
|
||||
|
||||
const promise = retryWithBackoff(mockFn, {
|
||||
maxAttempts: 3,
|
||||
initialDelayMs: 100,
|
||||
signal: abortController.signal,
|
||||
onRetry,
|
||||
});
|
||||
|
||||
await expect(promise).rejects.toThrow(
|
||||
expect.objectContaining({ name: 'AbortError' }),
|
||||
);
|
||||
expect(onRetry).not.toHaveBeenCalled();
|
||||
expect(debugLogger.warn).not.toHaveBeenCalled();
|
||||
expect(mockFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should not emit onRetry when aborted before content retry handling', async () => {
|
||||
const abortController = new AbortController();
|
||||
const onRetry = vi.fn();
|
||||
const shouldRetryOnContent = vi.fn().mockImplementation(() => {
|
||||
abortController.abort();
|
||||
return true;
|
||||
});
|
||||
const mockFn = vi.fn().mockResolvedValue({});
|
||||
|
||||
const promise = retryWithBackoff(mockFn, {
|
||||
maxAttempts: 3,
|
||||
initialDelayMs: 100,
|
||||
signal: abortController.signal,
|
||||
onRetry,
|
||||
shouldRetryOnContent,
|
||||
});
|
||||
|
||||
await expect(promise).rejects.toThrow(
|
||||
expect.objectContaining({ name: 'AbortError' }),
|
||||
);
|
||||
expect(onRetry).not.toHaveBeenCalled();
|
||||
expect(debugLogger.warn).not.toHaveBeenCalled();
|
||||
expect(shouldRetryOnContent).toHaveBeenCalledTimes(1);
|
||||
expect(mockFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should trigger fallback for OAuth personal users on persistent 500 errors', async () => {
|
||||
const fallbackCallback = vi.fn().mockResolvedValue('gemini-2.5-flash');
|
||||
|
||||
|
||||
@@ -232,6 +232,11 @@ export async function retryWithBackoff<T>(
|
||||
|
||||
let attempt = 0;
|
||||
let currentDelay = initialDelayMs;
|
||||
const throwIfAborted = () => {
|
||||
if (signal?.aborted) {
|
||||
throw createAbortError();
|
||||
}
|
||||
};
|
||||
|
||||
while (attempt < maxAttempts) {
|
||||
if (signal?.aborted) {
|
||||
@@ -246,6 +251,7 @@ export async function retryWithBackoff<T>(
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
||||
shouldRetryOnContent(result as GenerateContentResponse)
|
||||
) {
|
||||
throwIfAborted();
|
||||
const jitter = currentDelay * 0.3 * (Math.random() * 2 - 1);
|
||||
const delayWithJitter = Math.max(0, currentDelay + jitter);
|
||||
if (onRetry) {
|
||||
@@ -266,6 +272,7 @@ export async function retryWithBackoff<T>(
|
||||
if (error instanceof Error && error.name === 'AbortError') {
|
||||
throw error;
|
||||
}
|
||||
throwIfAborted();
|
||||
|
||||
const classifiedError = classifyGoogleError(error);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user