summaryrefslogtreecommitdiff
path: root/packages/core/src/utils/quotaErrorDetection.ts
diff options
context:
space:
mode:
authorBryan Morgan <[email protected]>2025-07-09 10:18:15 -0400
committerGitHub <[email protected]>2025-07-09 14:18:15 +0000
commitb0cce952860b9ff51a0f731fbb8a7649ead23530 (patch)
treefe38d1d2fd4e313f7802d835c64297827eca7817 /packages/core/src/utils/quotaErrorDetection.ts
parent8f2da86aa521c2a0c3f5bfc72abe346182d2f963 (diff)
Improve quota- and resource-related 429 error handling, also taking Code Assist customer tiers into consideration (#3609)
Diffstat (limited to 'packages/core/src/utils/quotaErrorDetection.ts')
-rw-r--r--packages/core/src/utils/quotaErrorDetection.ts82
1 files changed, 82 insertions, 0 deletions
diff --git a/packages/core/src/utils/quotaErrorDetection.ts b/packages/core/src/utils/quotaErrorDetection.ts
new file mode 100644
index 00000000..ec77f5ee
--- /dev/null
+++ b/packages/core/src/utils/quotaErrorDetection.ts
@@ -0,0 +1,82 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export interface ApiError {
+ error: {
+ code: number;
+ message: string;
+ status: string;
+ details: unknown[];
+ };
+}
+
+interface StructuredError {
+ message: string;
+ status?: number;
+}
+
+export function isApiError(error: unknown): error is ApiError {
+ return (
+ typeof error === 'object' &&
+ error !== null &&
+ 'error' in error &&
+ typeof (error as ApiError).error === 'object' &&
+ 'message' in (error as ApiError).error
+ );
+}
+
+export function isStructuredError(error: unknown): error is StructuredError {
+ return (
+ typeof error === 'object' &&
+ error !== null &&
+ 'message' in error &&
+ typeof (error as StructuredError).message === 'string'
+ );
+}
+
+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'"
+ // 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'");
+
+ if (typeof error === 'string') {
+ return checkMessage(error);
+ }
+
+ if (isStructuredError(error)) {
+ return checkMessage(error.message);
+ }
+
+ if (isApiError(error)) {
+ return checkMessage(error.error.message);
+ }
+
+ return false;
+}
+
+export function isGenericQuotaExceededError(error: unknown): boolean {
+ if (typeof error === 'string') {
+ return error.includes('Quota exceeded for quota metric');
+ }
+
+ if (isStructuredError(error)) {
+ return error.message.includes('Quota exceeded for quota metric');
+ }
+
+ if (isApiError(error)) {
+ return error.error.message.includes('Quota exceeded for quota metric');
+ }
+
+ return false;
+}