From 265b96e00781baf45d4b829086f3462d2aa454fd Mon Sep 17 00:00:00 2001 From: jnjpng Date: Fri, 27 Feb 2026 15:54:40 -0800 Subject: [PATCH] fix: normalize Cloudflare HTML errors in telemetry (#1210) Co-authored-by: Letta --- src/cli/App.tsx | 23 ++++++++++++++++------- src/cli/helpers/errorFormatter.ts | 12 ++++++++++++ 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/cli/App.tsx b/src/cli/App.tsx index 87cec61..92949b9 100644 --- a/src/cli/App.tsx +++ b/src/cli/App.tsx @@ -210,6 +210,7 @@ import { import { setErrorContext } from "./helpers/errorContext"; import { formatErrorDetails, + formatTelemetryErrorMessage, getRetryStatusMessage, isEncryptedContentError, } from "./helpers/errorFormatter"; @@ -362,6 +363,7 @@ function deriveReasoningEffort( ) return re; } + // Anthropic/Bedrock: effort field if ( modelSettings.provider_type === "anthropic" || @@ -3923,7 +3925,9 @@ export default function App({ // Log the conversation-busy error telemetry.trackError( "retry_conversation_busy", - errorDetail || "Conversation is busy", + formatTelemetryErrorMessage( + errorDetail || "Conversation is busy", + ), "pre_stream_retry", { httpStatus: @@ -3989,7 +3993,9 @@ export default function App({ // Log the error that triggered the retry telemetry.trackError( "retry_pre_stream_transient", - errorDetail || "Pre-stream transient error", + formatTelemetryErrorMessage( + errorDetail || "Pre-stream transient error", + ), "pre_stream_retry", { httpStatus: @@ -5234,9 +5240,11 @@ export default function App({ // Log the error that triggered the retry telemetry.trackError( "retry_post_stream_error", - detailFromRun || - fallbackError || - `Stream stopped: ${stopReasonToHandle}`, + formatTelemetryErrorMessage( + detailFromRun || + fallbackError || + `Stream stopped: ${stopReasonToHandle}`, + ), "post_stream_retry", { modelId: currentModelId || undefined, @@ -5366,9 +5374,10 @@ export default function App({ // — skip the generic "Something went wrong?" hint appendError(errorDetails, { ...errorTelemetryBase, - errorMessage: + errorMessage: formatTelemetryErrorMessage( serverErrorDetail || - `Stream stopped with reason: ${stopReasonToHandle}`, + `Stream stopped with reason: ${stopReasonToHandle}`, + ), }); if (!isEncryptedContentError(errorObject)) { diff --git a/src/cli/helpers/errorFormatter.ts b/src/cli/helpers/errorFormatter.ts index 4a3a523..be5505f 100644 --- a/src/cli/helpers/errorFormatter.ts +++ b/src/cli/helpers/errorFormatter.ts @@ -83,6 +83,18 @@ export function checkCloudflareEdgeError(text: string): string | undefined { return `${codeLabel}${statusSegment}${hostSegment}${raySegment}. This is usually a temporary edge/origin outage. Please retry in a moment.`; } +/** + * Normalize raw provider error payloads before sending to telemetry. + * Keeps telemetry concise by collapsing Cloudflare HTML pages into a + * single readable line while preserving non-Cloudflare messages as-is. + */ +export function formatTelemetryErrorMessage( + message: string | null | undefined, +): string { + if (!message) return "Unknown error"; + return checkCloudflareEdgeError(message) ?? message; +} + function getErrorReasons(e: APIError): string[] { const reasons = new Set();