mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-20 08:47:44 +00:00
Remove auto-execution on Flash in the event of a 429/Quota failover (#3662)
Co-authored-by: Jenna Inouye <jinouye@google.com>
This commit is contained in:
@@ -214,6 +214,8 @@ describe('editCorrector', () => {
|
||||
setAlwaysSkipModificationConfirmation: vi.fn((skip: boolean) => {
|
||||
configParams.alwaysSkipModificationConfirmation = skip;
|
||||
}),
|
||||
getQuotaErrorOccurred: vi.fn().mockReturnValue(false),
|
||||
setQuotaErrorOccurred: vi.fn(),
|
||||
} as unknown as Config;
|
||||
|
||||
callCount = 0;
|
||||
@@ -654,6 +656,8 @@ describe('editCorrector', () => {
|
||||
setAlwaysSkipModificationConfirmation: vi.fn((skip: boolean) => {
|
||||
configParams.alwaysSkipModificationConfirmation = skip;
|
||||
}),
|
||||
getQuotaErrorOccurred: vi.fn().mockReturnValue(false),
|
||||
setQuotaErrorOccurred: vi.fn(),
|
||||
} as unknown as Config;
|
||||
|
||||
callCount = 0;
|
||||
|
||||
@@ -41,14 +41,23 @@ export function isProQuotaExceededError(error: unknown): boolean {
|
||||
// Check for Pro quota exceeded errors by looking for the specific pattern
|
||||
// This will match patterns like:
|
||||
// - "Quota exceeded for quota metric 'Gemini 2.5 Pro Requests'"
|
||||
// - "Quota exceeded for quota metric 'Gemini 1.5-preview Pro Requests'"
|
||||
// - "Quota exceeded for quota metric 'Gemini beta-3.0 Pro Requests'"
|
||||
// - "Quota exceeded for quota metric 'Gemini experimental-v2 Pro Requests'"
|
||||
// - "Quota exceeded for quota metric 'Gemini 2.5-preview Pro Requests'"
|
||||
// We use string methods instead of regex to avoid ReDoS vulnerabilities
|
||||
|
||||
const checkMessage = (message: string): boolean =>
|
||||
message.includes("Quota exceeded for quota metric 'Gemini") &&
|
||||
message.includes("Pro Requests'");
|
||||
const checkMessage = (message: string): boolean => {
|
||||
console.log('[DEBUG] isProQuotaExceededError checking message:', message);
|
||||
const result =
|
||||
message.includes("Quota exceeded for quota metric 'Gemini") &&
|
||||
message.includes("Pro Requests'");
|
||||
console.log('[DEBUG] isProQuotaExceededError result:', result);
|
||||
return result;
|
||||
};
|
||||
|
||||
// Log the full error object to understand its structure
|
||||
console.log(
|
||||
'[DEBUG] isProQuotaExceededError - full error object:',
|
||||
JSON.stringify(error, null, 2),
|
||||
);
|
||||
|
||||
if (typeof error === 'string') {
|
||||
return checkMessage(error);
|
||||
@@ -62,6 +71,38 @@ export function isProQuotaExceededError(error: unknown): boolean {
|
||||
return checkMessage(error.error.message);
|
||||
}
|
||||
|
||||
// Check if it's a Gaxios error with response data
|
||||
if (error && typeof error === 'object' && 'response' in error) {
|
||||
const gaxiosError = error as {
|
||||
response?: {
|
||||
data?: unknown;
|
||||
};
|
||||
};
|
||||
if (gaxiosError.response && gaxiosError.response.data) {
|
||||
console.log(
|
||||
'[DEBUG] isProQuotaExceededError - checking response data:',
|
||||
gaxiosError.response.data,
|
||||
);
|
||||
if (typeof gaxiosError.response.data === 'string') {
|
||||
return checkMessage(gaxiosError.response.data);
|
||||
}
|
||||
if (
|
||||
typeof gaxiosError.response.data === 'object' &&
|
||||
gaxiosError.response.data !== null &&
|
||||
'error' in gaxiosError.response.data
|
||||
) {
|
||||
const errorData = gaxiosError.response.data as {
|
||||
error?: { message?: string };
|
||||
};
|
||||
return checkMessage(errorData.error?.message || '');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log(
|
||||
'[DEBUG] isProQuotaExceededError - no matching error format for:',
|
||||
error,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ export interface RetryOptions {
|
||||
onPersistent429?: (
|
||||
authType?: string,
|
||||
error?: unknown,
|
||||
) => Promise<string | null>;
|
||||
) => Promise<string | boolean | null>;
|
||||
authType?: string;
|
||||
}
|
||||
|
||||
@@ -102,13 +102,16 @@ export async function retryWithBackoff<T>(
|
||||
) {
|
||||
try {
|
||||
const fallbackModel = await onPersistent429(authType, error);
|
||||
if (fallbackModel) {
|
||||
if (fallbackModel !== false && fallbackModel !== null) {
|
||||
// Reset attempt counter and try with new model
|
||||
attempt = 0;
|
||||
consecutive429Count = 0;
|
||||
currentDelay = initialDelayMs;
|
||||
// With the model updated, we continue to the next attempt
|
||||
continue;
|
||||
} else {
|
||||
// Fallback handler returned null/false, meaning don't continue - stop retry process
|
||||
throw error;
|
||||
}
|
||||
} catch (fallbackError) {
|
||||
// If fallback fails, continue with original error
|
||||
@@ -126,13 +129,16 @@ export async function retryWithBackoff<T>(
|
||||
) {
|
||||
try {
|
||||
const fallbackModel = await onPersistent429(authType, error);
|
||||
if (fallbackModel) {
|
||||
if (fallbackModel !== false && fallbackModel !== null) {
|
||||
// Reset attempt counter and try with new model
|
||||
attempt = 0;
|
||||
consecutive429Count = 0;
|
||||
currentDelay = initialDelayMs;
|
||||
// With the model updated, we continue to the next attempt
|
||||
continue;
|
||||
} else {
|
||||
// Fallback handler returned null/false, meaning don't continue - stop retry process
|
||||
throw error;
|
||||
}
|
||||
} catch (fallbackError) {
|
||||
// If fallback fails, continue with original error
|
||||
@@ -155,13 +161,16 @@ export async function retryWithBackoff<T>(
|
||||
) {
|
||||
try {
|
||||
const fallbackModel = await onPersistent429(authType, error);
|
||||
if (fallbackModel) {
|
||||
if (fallbackModel !== false && fallbackModel !== null) {
|
||||
// Reset attempt counter and try with new model
|
||||
attempt = 0;
|
||||
consecutive429Count = 0;
|
||||
currentDelay = initialDelayMs;
|
||||
// With the model updated, we continue to the next attempt
|
||||
continue;
|
||||
} else {
|
||||
// Fallback handler returned null/false, meaning don't continue - stop retry process
|
||||
throw error;
|
||||
}
|
||||
} catch (fallbackError) {
|
||||
// If fallback fails, continue with original error
|
||||
|
||||
Reference in New Issue
Block a user