summaryrefslogtreecommitdiff
path: root/packages/cli/src/ui/utils/errorParsing.test.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/cli/src/ui/utils/errorParsing.test.ts')
-rw-r--r--packages/cli/src/ui/utils/errorParsing.test.ts378
1 files changed, 0 insertions, 378 deletions
diff --git a/packages/cli/src/ui/utils/errorParsing.test.ts b/packages/cli/src/ui/utils/errorParsing.test.ts
deleted file mode 100644
index 770dffad..00000000
--- a/packages/cli/src/ui/utils/errorParsing.test.ts
+++ /dev/null
@@ -1,378 +0,0 @@
-/**
- * @license
- * Copyright 2025 Google LLC
- * SPDX-License-Identifier: Apache-2.0
- */
-
-import { describe, it, expect } from 'vitest';
-import { parseAndFormatApiError } from './errorParsing.js';
-import {
- AuthType,
- UserTierId,
- DEFAULT_GEMINI_FLASH_MODEL,
- isProQuotaExceededError,
-} from '@google/gemini-cli-core';
-
-describe('parseAndFormatApiError', () => {
- const _enterpriseMessage =
- 'upgrade to a Gemini Code Assist Standard or Enterprise plan with higher limits';
- const vertexMessage = 'request a quota increase through Vertex';
- const geminiMessage = 'request a quota increase through AI Studio';
-
- it('should format a valid API error JSON', () => {
- const errorMessage =
- 'got status: 400 Bad Request. {"error":{"code":400,"message":"API key not valid. Please pass a valid API key.","status":"INVALID_ARGUMENT"}}';
- const expected =
- '[API Error: API key not valid. Please pass a valid API key. (Status: INVALID_ARGUMENT)]';
- expect(parseAndFormatApiError(errorMessage)).toBe(expected);
- });
-
- it('should format a 429 API error with the default message', () => {
- const errorMessage =
- 'got status: 429 Too Many Requests. {"error":{"code":429,"message":"Rate limit exceeded","status":"RESOURCE_EXHAUSTED"}}';
- const result = parseAndFormatApiError(
- errorMessage,
- undefined,
- undefined,
- 'gemini-2.5-pro',
- DEFAULT_GEMINI_FLASH_MODEL,
- );
- expect(result).toContain('[API Error: Rate limit exceeded');
- expect(result).toContain(
- 'Possible quota limitations in place or slow response times detected. Switching to the gemini-2.5-flash model',
- );
- });
-
- it('should format a 429 API error with the personal message', () => {
- const errorMessage =
- 'got status: 429 Too Many Requests. {"error":{"code":429,"message":"Rate limit exceeded","status":"RESOURCE_EXHAUSTED"}}';
- const result = parseAndFormatApiError(
- errorMessage,
- AuthType.LOGIN_WITH_GOOGLE,
- undefined,
- 'gemini-2.5-pro',
- DEFAULT_GEMINI_FLASH_MODEL,
- );
- expect(result).toContain('[API Error: Rate limit exceeded');
- expect(result).toContain(
- 'Possible quota limitations in place or slow response times detected. Switching to the gemini-2.5-flash model',
- );
- });
-
- it('should format a 429 API error with the vertex message', () => {
- const errorMessage =
- 'got status: 429 Too Many Requests. {"error":{"code":429,"message":"Rate limit exceeded","status":"RESOURCE_EXHAUSTED"}}';
- const result = parseAndFormatApiError(errorMessage, AuthType.USE_VERTEX_AI);
- expect(result).toContain('[API Error: Rate limit exceeded');
- expect(result).toContain(vertexMessage);
- });
-
- it('should return the original message if it is not a JSON error', () => {
- const errorMessage = 'This is a plain old error message';
- expect(parseAndFormatApiError(errorMessage)).toBe(
- `[API Error: ${errorMessage}]`,
- );
- });
-
- it('should return the original message for malformed JSON', () => {
- const errorMessage = '[Stream Error: {"error": "malformed}';
- expect(parseAndFormatApiError(errorMessage)).toBe(
- `[API Error: ${errorMessage}]`,
- );
- });
-
- it('should handle JSON that does not match the ApiError structure', () => {
- const errorMessage = '[Stream Error: {"not_an_error": "some other json"}]';
- expect(parseAndFormatApiError(errorMessage)).toBe(
- `[API Error: ${errorMessage}]`,
- );
- });
-
- it('should format a nested API error', () => {
- const nestedErrorMessage = JSON.stringify({
- error: {
- code: 429,
- message:
- "Gemini 2.5 Pro Preview doesn't have a free quota tier. For more information on this error, head to: https://ai.google.dev/gemini-api/docs/rate-limits.",
- status: 'RESOURCE_EXHAUSTED',
- },
- });
-
- const errorMessage = JSON.stringify({
- error: {
- code: 429,
- message: nestedErrorMessage,
- status: 'Too Many Requests',
- },
- });
-
- const result = parseAndFormatApiError(errorMessage, AuthType.USE_GEMINI);
- expect(result).toContain('Gemini 2.5 Pro Preview');
- expect(result).toContain(geminiMessage);
- });
-
- it('should format a StructuredError', () => {
- const error: StructuredError = {
- message: 'A structured error occurred',
- status: 500,
- };
- const expected = '[API Error: A structured error occurred]';
- expect(parseAndFormatApiError(error)).toBe(expected);
- });
-
- it('should format a 429 StructuredError with the vertex message', () => {
- const error: StructuredError = {
- message: 'Rate limit exceeded',
- status: 429,
- };
- const result = parseAndFormatApiError(error, AuthType.USE_VERTEX_AI);
- expect(result).toContain('[API Error: Rate limit exceeded]');
- expect(result).toContain(vertexMessage);
- });
-
- it('should handle an unknown error type', () => {
- const error = 12345;
- const expected = '[API Error: An unknown error occurred.]';
- expect(parseAndFormatApiError(error)).toBe(expected);
- });
-
- it('should format a 429 API error with Pro quota exceeded message for Google auth (Free tier)', () => {
- const errorMessage =
- 'got status: 429 Too Many Requests. {"error":{"code":429,"message":"Quota exceeded for quota metric \'Gemini 2.5 Pro Requests\' and limit \'RequestsPerDay\' of service \'generativelanguage.googleapis.com\' for consumer \'project_number:123456789\'.","status":"RESOURCE_EXHAUSTED"}}';
- const result = parseAndFormatApiError(
- errorMessage,
- AuthType.LOGIN_WITH_GOOGLE,
- undefined,
- 'gemini-2.5-pro',
- DEFAULT_GEMINI_FLASH_MODEL,
- );
- expect(result).toContain(
- "[API Error: Quota exceeded for quota metric 'Gemini 2.5 Pro Requests'",
- );
- expect(result).toContain(
- 'You have reached your daily gemini-2.5-pro quota limit',
- );
- expect(result).toContain(
- 'upgrade to a Gemini Code Assist Standard or Enterprise plan',
- );
- });
-
- it('should format a regular 429 API error with standard message for Google auth', () => {
- const errorMessage =
- 'got status: 429 Too Many Requests. {"error":{"code":429,"message":"Rate limit exceeded","status":"RESOURCE_EXHAUSTED"}}';
- const result = parseAndFormatApiError(
- errorMessage,
- AuthType.LOGIN_WITH_GOOGLE,
- undefined,
- 'gemini-2.5-pro',
- DEFAULT_GEMINI_FLASH_MODEL,
- );
- expect(result).toContain('[API Error: Rate limit exceeded');
- expect(result).toContain(
- 'Possible quota limitations in place or slow response times detected. Switching to the gemini-2.5-flash model',
- );
- expect(result).not.toContain(
- 'You have reached your daily gemini-2.5-pro quota limit',
- );
- });
-
- it('should format a 429 API error with generic quota exceeded message for Google auth', () => {
- const errorMessage =
- 'got status: 429 Too Many Requests. {"error":{"code":429,"message":"Quota exceeded for quota metric \'GenerationRequests\' and limit \'RequestsPerDay\' of service \'generativelanguage.googleapis.com\' for consumer \'project_number:123456789\'.","status":"RESOURCE_EXHAUSTED"}}';
- const result = parseAndFormatApiError(
- errorMessage,
- AuthType.LOGIN_WITH_GOOGLE,
- undefined,
- 'gemini-2.5-pro',
- DEFAULT_GEMINI_FLASH_MODEL,
- );
- expect(result).toContain(
- "[API Error: Quota exceeded for quota metric 'GenerationRequests'",
- );
- expect(result).toContain('You have reached your daily quota limit');
- expect(result).not.toContain(
- 'You have reached your daily Gemini 2.5 Pro quota limit',
- );
- });
-
- it('should prioritize Pro quota message over generic quota message for Google auth', () => {
- const errorMessage =
- 'got status: 429 Too Many Requests. {"error":{"code":429,"message":"Quota exceeded for quota metric \'Gemini 2.5 Pro Requests\' and limit \'RequestsPerDay\' of service \'generativelanguage.googleapis.com\' for consumer \'project_number:123456789\'.","status":"RESOURCE_EXHAUSTED"}}';
- const result = parseAndFormatApiError(
- errorMessage,
- AuthType.LOGIN_WITH_GOOGLE,
- undefined,
- 'gemini-2.5-pro',
- DEFAULT_GEMINI_FLASH_MODEL,
- );
- expect(result).toContain(
- "[API Error: Quota exceeded for quota metric 'Gemini 2.5 Pro Requests'",
- );
- expect(result).toContain(
- 'You have reached your daily gemini-2.5-pro quota limit',
- );
- expect(result).not.toContain('You have reached your daily quota limit');
- });
-
- it('should format a 429 API error with Pro quota exceeded message for Google auth (Standard tier)', () => {
- const errorMessage =
- 'got status: 429 Too Many Requests. {"error":{"code":429,"message":"Quota exceeded for quota metric \'Gemini 2.5 Pro Requests\' and limit \'RequestsPerDay\' of service \'generativelanguage.googleapis.com\' for consumer \'project_number:123456789\'.","status":"RESOURCE_EXHAUSTED"}}';
- const result = parseAndFormatApiError(
- errorMessage,
- AuthType.LOGIN_WITH_GOOGLE,
- UserTierId.STANDARD,
- 'gemini-2.5-pro',
- DEFAULT_GEMINI_FLASH_MODEL,
- );
- expect(result).toContain(
- "[API Error: Quota exceeded for quota metric 'Gemini 2.5 Pro Requests'",
- );
- expect(result).toContain(
- 'You have reached your daily gemini-2.5-pro quota limit',
- );
- expect(result).toContain(
- 'We appreciate you for choosing Gemini Code Assist and the Gemini CLI',
- );
- expect(result).not.toContain(
- 'upgrade to a Gemini Code Assist Standard or Enterprise plan',
- );
- });
-
- it('should format a 429 API error with Pro quota exceeded message for Google auth (Legacy tier)', () => {
- const errorMessage =
- 'got status: 429 Too Many Requests. {"error":{"code":429,"message":"Quota exceeded for quota metric \'Gemini 2.5 Pro Requests\' and limit \'RequestsPerDay\' of service \'generativelanguage.googleapis.com\' for consumer \'project_number:123456789\'.","status":"RESOURCE_EXHAUSTED"}}';
- const result = parseAndFormatApiError(
- errorMessage,
- AuthType.LOGIN_WITH_GOOGLE,
- UserTierId.LEGACY,
- 'gemini-2.5-pro',
- DEFAULT_GEMINI_FLASH_MODEL,
- );
- expect(result).toContain(
- "[API Error: Quota exceeded for quota metric 'Gemini 2.5 Pro Requests'",
- );
- expect(result).toContain(
- 'You have reached your daily gemini-2.5-pro quota limit',
- );
- expect(result).toContain(
- 'We appreciate you for choosing Gemini Code Assist and the Gemini CLI',
- );
- expect(result).not.toContain(
- 'upgrade to a Gemini Code Assist Standard or Enterprise plan',
- );
- });
-
- it('should handle different Gemini 2.5 version strings in Pro quota exceeded errors', () => {
- const errorMessage25 =
- 'got status: 429 Too Many Requests. {"error":{"code":429,"message":"Quota exceeded for quota metric \'Gemini 2.5 Pro Requests\' and limit \'RequestsPerDay\' of service \'generativelanguage.googleapis.com\' for consumer \'project_number:123456789\'.","status":"RESOURCE_EXHAUSTED"}}';
- const errorMessagePreview =
- 'got status: 429 Too Many Requests. {"error":{"code":429,"message":"Quota exceeded for quota metric \'Gemini 2.5-preview Pro Requests\' and limit \'RequestsPerDay\' of service \'generativelanguage.googleapis.com\' for consumer \'project_number:123456789\'.","status":"RESOURCE_EXHAUSTED"}}';
-
- const result25 = parseAndFormatApiError(
- errorMessage25,
- AuthType.LOGIN_WITH_GOOGLE,
- undefined,
- 'gemini-2.5-pro',
- DEFAULT_GEMINI_FLASH_MODEL,
- );
- const resultPreview = parseAndFormatApiError(
- errorMessagePreview,
- AuthType.LOGIN_WITH_GOOGLE,
- undefined,
- 'gemini-2.5-preview-pro',
- DEFAULT_GEMINI_FLASH_MODEL,
- );
-
- expect(result25).toContain(
- 'You have reached your daily gemini-2.5-pro quota limit',
- );
- expect(resultPreview).toContain(
- 'You have reached your daily gemini-2.5-preview-pro quota limit',
- );
- expect(result25).toContain(
- 'upgrade to a Gemini Code Assist Standard or Enterprise plan',
- );
- expect(resultPreview).toContain(
- 'upgrade to a Gemini Code Assist Standard or Enterprise plan',
- );
- });
-
- it('should not match non-Pro models with similar version strings', () => {
- // Test that Flash models with similar version strings don't match
- expect(
- isProQuotaExceededError(
- "Quota exceeded for quota metric 'Gemini 2.5 Flash Requests' and limit",
- ),
- ).toBe(false);
- expect(
- isProQuotaExceededError(
- "Quota exceeded for quota metric 'Gemini 2.5-preview Flash Requests' and limit",
- ),
- ).toBe(false);
-
- // Test other model types
- expect(
- isProQuotaExceededError(
- "Quota exceeded for quota metric 'Gemini 2.5 Ultra Requests' and limit",
- ),
- ).toBe(false);
- expect(
- isProQuotaExceededError(
- "Quota exceeded for quota metric 'Gemini 2.5 Standard Requests' and limit",
- ),
- ).toBe(false);
-
- // Test generic quota messages
- expect(
- isProQuotaExceededError(
- "Quota exceeded for quota metric 'GenerationRequests' and limit",
- ),
- ).toBe(false);
- expect(
- isProQuotaExceededError(
- "Quota exceeded for quota metric 'EmbeddingRequests' and limit",
- ),
- ).toBe(false);
- });
-
- it('should format a generic quota exceeded message for Google auth (Standard tier)', () => {
- const errorMessage =
- 'got status: 429 Too Many Requests. {"error":{"code":429,"message":"Quota exceeded for quota metric \'GenerationRequests\' and limit \'RequestsPerDay\' of service \'generativelanguage.googleapis.com\' for consumer \'project_number:123456789\'.","status":"RESOURCE_EXHAUSTED"}}';
- const result = parseAndFormatApiError(
- errorMessage,
- AuthType.LOGIN_WITH_GOOGLE,
- UserTierId.STANDARD,
- 'gemini-2.5-pro',
- DEFAULT_GEMINI_FLASH_MODEL,
- );
- expect(result).toContain(
- "[API Error: Quota exceeded for quota metric 'GenerationRequests'",
- );
- expect(result).toContain('You have reached your daily quota limit');
- expect(result).toContain(
- 'We appreciate you for choosing Gemini Code Assist and the Gemini CLI',
- );
- expect(result).not.toContain(
- 'upgrade to a Gemini Code Assist Standard or Enterprise plan',
- );
- });
-
- it('should format a regular 429 API error with standard message for Google auth (Standard tier)', () => {
- const errorMessage =
- 'got status: 429 Too Many Requests. {"error":{"code":429,"message":"Rate limit exceeded","status":"RESOURCE_EXHAUSTED"}}';
- const result = parseAndFormatApiError(
- errorMessage,
- AuthType.LOGIN_WITH_GOOGLE,
- UserTierId.STANDARD,
- 'gemini-2.5-pro',
- DEFAULT_GEMINI_FLASH_MODEL,
- );
- expect(result).toContain('[API Error: Rate limit exceeded');
- expect(result).toContain(
- 'We appreciate you for choosing Gemini Code Assist and the Gemini CLI',
- );
- expect(result).not.toContain(
- 'upgrade to a Gemini Code Assist Standard or Enterprise plan',
- );
- });
-});