mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-07-16 13:00:39 -07:00
Revert "fix: handle request retries and model fallback correctly" (#11164)
This commit is contained in:
@@ -1,205 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2025 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { describe, it, expect, vi, afterEach } from 'vitest';
|
||||
import {
|
||||
classifyGoogleError,
|
||||
RetryableQuotaError,
|
||||
TerminalQuotaError,
|
||||
} from './googleQuotaErrors.js';
|
||||
import * as errorParser from './googleErrors.js';
|
||||
import type { GoogleApiError } from './googleErrors.js';
|
||||
|
||||
describe('classifyGoogleError', () => {
|
||||
afterEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
it('should return original error if not a Google API error', () => {
|
||||
const regularError = new Error('Something went wrong');
|
||||
vi.spyOn(errorParser, 'parseGoogleApiError').mockReturnValue(null);
|
||||
const result = classifyGoogleError(regularError);
|
||||
expect(result).toBe(regularError);
|
||||
});
|
||||
|
||||
it('should return original error if code is not 429', () => {
|
||||
const apiError: GoogleApiError = {
|
||||
code: 500,
|
||||
message: 'Server error',
|
||||
details: [],
|
||||
};
|
||||
vi.spyOn(errorParser, 'parseGoogleApiError').mockReturnValue(apiError);
|
||||
const originalError = new Error();
|
||||
const result = classifyGoogleError(originalError);
|
||||
expect(result).toBe(originalError);
|
||||
expect(result).not.toBeInstanceOf(TerminalQuotaError);
|
||||
expect(result).not.toBeInstanceOf(RetryableQuotaError);
|
||||
});
|
||||
|
||||
it('should return TerminalQuotaError for daily quota violations in QuotaFailure', () => {
|
||||
const apiError: GoogleApiError = {
|
||||
code: 429,
|
||||
message: 'Quota exceeded',
|
||||
details: [
|
||||
{
|
||||
'@type': 'type.googleapis.com/google.rpc.QuotaFailure',
|
||||
violations: [
|
||||
{
|
||||
subject: 'user',
|
||||
description: 'daily limit',
|
||||
quotaId: 'RequestsPerDay-limit',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
vi.spyOn(errorParser, 'parseGoogleApiError').mockReturnValue(apiError);
|
||||
const result = classifyGoogleError(new Error());
|
||||
expect(result).toBeInstanceOf(TerminalQuotaError);
|
||||
expect((result as TerminalQuotaError).cause).toBe(apiError);
|
||||
});
|
||||
|
||||
it('should return TerminalQuotaError for daily quota violations in ErrorInfo', () => {
|
||||
const apiError: GoogleApiError = {
|
||||
code: 429,
|
||||
message: 'Quota exceeded',
|
||||
details: [
|
||||
{
|
||||
'@type': 'type.googleapis.com/google.rpc.ErrorInfo',
|
||||
reason: 'QUOTA_EXCEEDED',
|
||||
domain: 'googleapis.com',
|
||||
metadata: {
|
||||
quota_limit: 'RequestsPerDay_PerProject_PerUser',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
vi.spyOn(errorParser, 'parseGoogleApiError').mockReturnValue(apiError);
|
||||
const result = classifyGoogleError(new Error());
|
||||
expect(result).toBeInstanceOf(TerminalQuotaError);
|
||||
});
|
||||
|
||||
it('should return TerminalQuotaError for long retry delays', () => {
|
||||
const apiError: GoogleApiError = {
|
||||
code: 429,
|
||||
message: 'Too many requests',
|
||||
details: [
|
||||
{
|
||||
'@type': 'type.googleapis.com/google.rpc.RetryInfo',
|
||||
retryDelay: '301s', // > 5 minutes
|
||||
},
|
||||
],
|
||||
};
|
||||
vi.spyOn(errorParser, 'parseGoogleApiError').mockReturnValue(apiError);
|
||||
const result = classifyGoogleError(new Error());
|
||||
expect(result).toBeInstanceOf(TerminalQuotaError);
|
||||
});
|
||||
|
||||
it('should return RetryableQuotaError for short retry delays', () => {
|
||||
const apiError: GoogleApiError = {
|
||||
code: 429,
|
||||
message: 'Too many requests',
|
||||
details: [
|
||||
{
|
||||
'@type': 'type.googleapis.com/google.rpc.RetryInfo',
|
||||
retryDelay: '45.123s',
|
||||
},
|
||||
],
|
||||
};
|
||||
vi.spyOn(errorParser, 'parseGoogleApiError').mockReturnValue(apiError);
|
||||
const result = classifyGoogleError(new Error());
|
||||
expect(result).toBeInstanceOf(RetryableQuotaError);
|
||||
expect((result as RetryableQuotaError).retryDelayMs).toBe(45123);
|
||||
});
|
||||
|
||||
it('should return RetryableQuotaError for per-minute quota violations in QuotaFailure', () => {
|
||||
const apiError: GoogleApiError = {
|
||||
code: 429,
|
||||
message: 'Quota exceeded',
|
||||
details: [
|
||||
{
|
||||
'@type': 'type.googleapis.com/google.rpc.QuotaFailure',
|
||||
violations: [
|
||||
{
|
||||
subject: 'user',
|
||||
description: 'per minute limit',
|
||||
quotaId: 'RequestsPerMinute-limit',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
vi.spyOn(errorParser, 'parseGoogleApiError').mockReturnValue(apiError);
|
||||
const result = classifyGoogleError(new Error());
|
||||
expect(result).toBeInstanceOf(RetryableQuotaError);
|
||||
expect((result as RetryableQuotaError).retryDelayMs).toBe(60000);
|
||||
});
|
||||
|
||||
it('should return RetryableQuotaError for per-minute quota violations in ErrorInfo', () => {
|
||||
const apiError: GoogleApiError = {
|
||||
code: 429,
|
||||
message: 'Quota exceeded',
|
||||
details: [
|
||||
{
|
||||
'@type': 'type.googleapis.com/google.rpc.ErrorInfo',
|
||||
reason: 'QUOTA_EXCEEDED',
|
||||
domain: 'googleapis.com',
|
||||
metadata: {
|
||||
quota_limit: 'RequestsPerMinute_PerProject_PerUser',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
vi.spyOn(errorParser, 'parseGoogleApiError').mockReturnValue(apiError);
|
||||
const result = classifyGoogleError(new Error());
|
||||
expect(result).toBeInstanceOf(RetryableQuotaError);
|
||||
expect((result as RetryableQuotaError).retryDelayMs).toBe(60000);
|
||||
});
|
||||
|
||||
it('should prioritize daily limit over retry info', () => {
|
||||
const apiError: GoogleApiError = {
|
||||
code: 429,
|
||||
message: 'Quota exceeded',
|
||||
details: [
|
||||
{
|
||||
'@type': 'type.googleapis.com/google.rpc.QuotaFailure',
|
||||
violations: [
|
||||
{
|
||||
subject: 'user',
|
||||
description: 'daily limit',
|
||||
quotaId: 'RequestsPerDay-limit',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
'@type': 'type.googleapis.com/google.rpc.RetryInfo',
|
||||
retryDelay: '10s',
|
||||
},
|
||||
],
|
||||
};
|
||||
vi.spyOn(errorParser, 'parseGoogleApiError').mockReturnValue(apiError);
|
||||
const result = classifyGoogleError(new Error());
|
||||
expect(result).toBeInstanceOf(TerminalQuotaError);
|
||||
});
|
||||
|
||||
it('should return original error for 429 without specific details', () => {
|
||||
const apiError: GoogleApiError = {
|
||||
code: 429,
|
||||
message: 'Too many requests',
|
||||
details: [
|
||||
{
|
||||
'@type': 'type.googleapis.com/google.rpc.DebugInfo',
|
||||
detail: 'some debug info',
|
||||
stackEntries: [],
|
||||
},
|
||||
],
|
||||
};
|
||||
vi.spyOn(errorParser, 'parseGoogleApiError').mockReturnValue(apiError);
|
||||
const originalError = new Error();
|
||||
const result = classifyGoogleError(originalError);
|
||||
expect(result).toBe(originalError);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user