diff options
| author | Scott Densmore <[email protected]> | 2025-06-07 22:04:57 -0700 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-06-07 22:04:57 -0700 |
| commit | b46f22093145760eaf8cefafd0050597bfb44249 (patch) | |
| tree | eeb3eb26e2289c1d5feef272745c105a2dbfca93 /packages/cli/src/ui/utils/errorParsing.ts | |
| parent | 6e4b84a60d0f94ba772b9872385d1c4021090786 (diff) | |
feat(cli): improve API error parsing and display (#829)
Diffstat (limited to 'packages/cli/src/ui/utils/errorParsing.ts')
| -rw-r--r-- | packages/cli/src/ui/utils/errorParsing.ts | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/packages/cli/src/ui/utils/errorParsing.ts b/packages/cli/src/ui/utils/errorParsing.ts new file mode 100644 index 00000000..aec337b6 --- /dev/null +++ b/packages/cli/src/ui/utils/errorParsing.ts @@ -0,0 +1,56 @@ +/** + * @license + * Copyright 2025 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +export interface ApiError { + error: { + code: number; + message: string; + status: string; + details: unknown[]; + }; +} + +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 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. + } + + const jsonString = errorMessage.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; + } + } catch (_e) { + // It's not a nested JSON error, so we just use the message as is. + } + return `API Error: ${finalMessage} (Status: ${error.error.status})`; + } + } catch (_e) { + // Not a valid JSON, fall through and return the original message. + } + + return errorMessage; +} |
