diff options
| author | Abhi <[email protected]> | 2025-06-23 17:30:13 -0400 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-06-23 21:30:13 +0000 |
| commit | dc76bcc433d58d879f8850ac777d2cd239dad611 (patch) | |
| tree | 89458926149f83721f00f09a5b5b3130d571bda5 /packages/cli/src/ui/utils/errorParsing.ts | |
| parent | 21e6a36cf1b17ff126b3d0253e68a6f3ebfc7c36 (diff) | |
Add error messaging for 429 errors (#1316)
Diffstat (limited to 'packages/cli/src/ui/utils/errorParsing.ts')
| -rw-r--r-- | packages/cli/src/ui/utils/errorParsing.ts | 72 |
1 files changed, 50 insertions, 22 deletions
diff --git a/packages/cli/src/ui/utils/errorParsing.ts b/packages/cli/src/ui/utils/errorParsing.ts index aec337b6..1aca15ae 100644 --- a/packages/cli/src/ui/utils/errorParsing.ts +++ b/packages/cli/src/ui/utils/errorParsing.ts @@ -4,6 +4,11 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { StructuredError } from '@gemini-cli/core'; + +const RATE_LIMIT_ERROR_MESSAGE = + '\nPlease wait and try again later. To increase your limits, upgrade to a plan with higher limits, or use /auth to switch to using a paid API key from AI Studio at https://aistudio.google.com/apikey'; + export interface ApiError { error: { code: number; @@ -23,34 +28,57 @@ function isApiError(error: unknown): error is ApiError { ); } -export function parseAndFormatApiError(errorMessage: string): string { - // The error message might be prefixed with some text, like "[Stream Error: ...]". - // We want to find the start of the JSON object. - const jsonStart = errorMessage.indexOf('{'); - if (jsonStart === -1) { - return errorMessage; // Not a JSON error, return as is. +function isStructuredError(error: unknown): error is StructuredError { + return ( + typeof error === 'object' && + error !== null && + 'message' in error && + typeof (error as StructuredError).message === 'string' + ); +} + +export function parseAndFormatApiError(error: unknown): string { + if (isStructuredError(error)) { + let text = `[API Error: ${error.message}]`; + if (error.status === 429) { + text += RATE_LIMIT_ERROR_MESSAGE; + } + return text; } - const jsonString = errorMessage.substring(jsonStart); + // The error message might be a string containing a JSON object. + if (typeof error === 'string') { + const jsonStart = error.indexOf('{'); + if (jsonStart === -1) { + return `[API Error: ${error}]`; // Not a JSON error, return as is. + } + + const jsonString = error.substring(jsonStart); - try { - const error = JSON.parse(jsonString) as unknown; - if (isApiError(error)) { - let finalMessage = error.error.message; - try { - // See if the message is a stringified JSON with another error - const nestedError = JSON.parse(finalMessage) as unknown; - if (isApiError(nestedError)) { - finalMessage = nestedError.error.message; + try { + const parsedError = JSON.parse(jsonString) as unknown; + if (isApiError(parsedError)) { + let finalMessage = parsedError.error.message; + try { + // See if the message is a stringified JSON with another error + const nestedError = JSON.parse(finalMessage) as unknown; + if (isApiError(nestedError)) { + finalMessage = nestedError.error.message; + } + } catch (_e) { + // It's not a nested JSON error, so we just use the message as is. + } + let text = `[API Error: ${finalMessage} (Status: ${parsedError.error.status})]`; + if (parsedError.error.code === 429) { + text += RATE_LIMIT_ERROR_MESSAGE; } - } catch (_e) { - // It's not a nested JSON error, so we just use the message as is. + return text; } - return `API Error: ${finalMessage} (Status: ${error.error.status})`; + } catch (_e) { + // Not a valid JSON, fall through and return the original message. } - } catch (_e) { - // Not a valid JSON, fall through and return the original message. + return `[API Error: ${error}]`; } - return errorMessage; + return '[API Error: An unknown error occurred.]'; } |
