Skip to content
17 changes: 17 additions & 0 deletions packages/core/src/utils/googleQuotaErrors.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -806,4 +806,21 @@ describe('classifyGoogleError', () => {
const result = classifyGoogleError(new Error());
expect(result).toBeInstanceOf(ValidationRequiredError);
});

it('should return TerminalQuotaError when limit is 0 even if message contains "Please retry in Xs"', () => {
const complexError = {
error: {
message:
'{"error": {"code": 429, "status": 429, "message": "You exceeded your current quota, please check your plan and billing details. For more information on this error, head to: https://ai.google.dev/gemini-api/docs/rate-limits. To monitor your current usage, head to: https://ai.dev/usage?tab=rate-limit. \\n* Quota exceeded for metric: generativelanguage.googleapis.com/generate_content_free_tier_requests, limit: 0\\nPlease retry in 59.906331105s.", "details": [{"detail": "??? to (unknown) : APP_ERROR(8) You exceeded your current quota, please check your plan and billing details. For more information on this error, head to: https://ai.google.dev/gemini-api/docs/rate-limits. To monitor your current usage, head to: https://ai.dev/usage?tab=rate-limit. \\n* Quota exceeded for metric: generativelanguage.googleapis.com/generate_content_free_tier_requests, limit: 0\\nPlease retry in 59.906331105s."}]}}',
code: 429,
status: 'Too Many Requests',
},
};
const rawError = new Error(JSON.stringify(complexError));
vi.spyOn(errorParser, 'parseGoogleApiError').mockReturnValue(null);
Comment thread
luisfelipe-alt marked this conversation as resolved.
Resolved

const result = classifyGoogleError(rawError);

expect(result).toBeInstanceOf(TerminalQuotaError);
});
Comment thread
luisfelipe-alt marked this conversation as resolved.
Resolved
});
10 changes: 10 additions & 0 deletions packages/core/src/utils/googleQuotaErrors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,16 @@ export function classifyGoogleError(error: unknown): unknown {
const errorMessage =
googleApiError?.message ||
(error instanceof Error ? error.message : String(error));

if (/limit:\s*0(?!\d|\.)/.test(errorMessage)) {
Comment thread
luisfelipe-alt marked this conversation as resolved.
Resolved
const cause = googleApiError ?? {
code: status ?? 429,
message: errorMessage,
details: [],
};
return new TerminalQuotaError(errorMessage, cause);
}

const match = errorMessage.match(/Please retry in ([0-9.]+(?:ms|s))/);
if (match?.[1]) {
const retryDelaySeconds = parseDurationInSeconds(match[1]);
Expand Down