From cdacb796a888c15e5939ff117c30da3f80c1703a Mon Sep 17 00:00:00 2001 From: Waleed Date: Tue, 17 Feb 2026 14:20:31 -0800 Subject: [PATCH] improvement(providers): replace @ts-ignore with typed ProviderError class (#3235) --- apps/sim/providers/anthropic/core.ts | 17 +++++------------ apps/sim/providers/azure-openai/index.ts | 11 ++++------- apps/sim/providers/bedrock/index.ts | 16 +++++++--------- apps/sim/providers/cerebras/index.ts | 9 +++------ apps/sim/providers/deepseek/index.ts | 9 +++------ apps/sim/providers/groq/index.ts | 9 +++------ apps/sim/providers/mistral/index.ts | 9 +++------ apps/sim/providers/ollama/index.ts | 9 +++------ apps/sim/providers/openai/core.ts | 9 +++------ apps/sim/providers/openrouter/index.ts | 18 +++++++++--------- apps/sim/providers/types.ts | 18 ++++++++++++++++++ apps/sim/providers/vllm/index.ts | 20 +++++--------------- apps/sim/providers/xai/index.ts | 12 +++++------- 13 files changed, 71 insertions(+), 95 deletions(-) diff --git a/apps/sim/providers/anthropic/core.ts b/apps/sim/providers/anthropic/core.ts index dcb2b9c14..3a31b19ac 100644 --- a/apps/sim/providers/anthropic/core.ts +++ b/apps/sim/providers/anthropic/core.ts @@ -14,6 +14,7 @@ import { supportsNativeStructuredOutputs, } from '@/providers/models' import type { ProviderRequest, ProviderResponse, TimeSegment } from '@/providers/types' +import { ProviderError } from '@/providers/types' import { calculateCost, prepareToolExecution, @@ -842,15 +843,11 @@ export async function executeAnthropicProviderRequest( duration: totalDuration, }) - const enhancedError = new Error(error instanceof Error ? error.message : String(error)) - // @ts-ignore - enhancedError.timing = { + throw new ProviderError(error instanceof Error ? error.message : String(error), { startTime: providerStartTimeISO, endTime: providerEndTimeISO, duration: totalDuration, - } - - throw enhancedError + }) } } @@ -1299,14 +1296,10 @@ export async function executeAnthropicProviderRequest( duration: totalDuration, }) - const enhancedError = new Error(error instanceof Error ? error.message : String(error)) - // @ts-ignore - enhancedError.timing = { + throw new ProviderError(error instanceof Error ? error.message : String(error), { startTime: providerStartTimeISO, endTime: providerEndTimeISO, duration: totalDuration, - } - - throw enhancedError + }) } } diff --git a/apps/sim/providers/azure-openai/index.ts b/apps/sim/providers/azure-openai/index.ts index d8b6c268c..3b711acd6 100644 --- a/apps/sim/providers/azure-openai/index.ts +++ b/apps/sim/providers/azure-openai/index.ts @@ -30,6 +30,7 @@ import type { ProviderResponse, TimeSegment, } from '@/providers/types' +import { ProviderError } from '@/providers/types' import { calculateCost, prepareToolExecution, @@ -251,7 +252,7 @@ async function executeChatCompletionsRequest( output: currentResponse.usage?.completion_tokens || 0, total: currentResponse.usage?.total_tokens || 0, } - const toolCalls: (FunctionCallResponse & { success: boolean })[] = [] + const toolCalls: FunctionCallResponse[] = [] const toolResults: Record[] = [] const currentMessages = [...allMessages] let iterationCount = 0 @@ -577,15 +578,11 @@ async function executeChatCompletionsRequest( duration: totalDuration, }) - const enhancedError = new Error(error instanceof Error ? error.message : String(error)) - // @ts-ignore - Adding timing property to the error - enhancedError.timing = { + throw new ProviderError(error instanceof Error ? error.message : String(error), { startTime: providerStartTimeISO, endTime: providerEndTimeISO, duration: totalDuration, - } - - throw enhancedError + }) } } diff --git a/apps/sim/providers/bedrock/index.ts b/apps/sim/providers/bedrock/index.ts index e602627b7..1d36af786 100644 --- a/apps/sim/providers/bedrock/index.ts +++ b/apps/sim/providers/bedrock/index.ts @@ -22,11 +22,13 @@ import { } from '@/providers/bedrock/utils' import { getProviderDefaultModel, getProviderModels } from '@/providers/models' import type { + FunctionCallResponse, ProviderConfig, ProviderRequest, ProviderResponse, TimeSegment, } from '@/providers/types' +import { ProviderError } from '@/providers/types' import { calculateCost, prepareToolExecution, @@ -419,8 +421,8 @@ export const bedrockProvider: ProviderConfig = { pricing: initialCost.pricing, } - const toolCalls: any[] = [] - const toolResults: any[] = [] + const toolCalls: FunctionCallResponse[] = [] + const toolResults: Record[] = [] const currentMessages = [...messages] let iterationCount = 0 let hasUsedForcedTool = false @@ -561,7 +563,7 @@ export const bedrockProvider: ProviderConfig = { let resultContent: any if (result.success) { - toolResults.push(result.output) + toolResults.push(result.output!) resultContent = result.output } else { resultContent = { @@ -903,15 +905,11 @@ export const bedrockProvider: ProviderConfig = { duration: totalDuration, }) - const enhancedError = new Error(error instanceof Error ? error.message : String(error)) - // @ts-ignore - enhancedError.timing = { + throw new ProviderError(error instanceof Error ? error.message : String(error), { startTime: providerStartTimeISO, endTime: providerEndTimeISO, duration: totalDuration, - } - - throw enhancedError + }) } }, } diff --git a/apps/sim/providers/cerebras/index.ts b/apps/sim/providers/cerebras/index.ts index c18560048..23daff85f 100644 --- a/apps/sim/providers/cerebras/index.ts +++ b/apps/sim/providers/cerebras/index.ts @@ -11,6 +11,7 @@ import type { ProviderResponse, TimeSegment, } from '@/providers/types' +import { ProviderError } from '@/providers/types' import { calculateCost, prepareToolExecution, @@ -539,15 +540,11 @@ export const cerebrasProvider: ProviderConfig = { duration: totalDuration, }) - const enhancedError = new Error(error instanceof Error ? error.message : String(error)) - // @ts-ignore - Adding timing property to error for debugging - enhancedError.timing = { + throw new ProviderError(error instanceof Error ? error.message : String(error), { startTime: providerStartTimeISO, endTime: providerEndTimeISO, duration: totalDuration, - } - - throw enhancedError + }) } }, } diff --git a/apps/sim/providers/deepseek/index.ts b/apps/sim/providers/deepseek/index.ts index 9ac7faa1d..693bf50c5 100644 --- a/apps/sim/providers/deepseek/index.ts +++ b/apps/sim/providers/deepseek/index.ts @@ -10,6 +10,7 @@ import type { ProviderResponse, TimeSegment, } from '@/providers/types' +import { ProviderError } from '@/providers/types' import { calculateCost, prepareToolExecution, @@ -538,15 +539,11 @@ export const deepseekProvider: ProviderConfig = { duration: totalDuration, }) - const enhancedError = new Error(error instanceof Error ? error.message : String(error)) - // @ts-ignore - enhancedError.timing = { + throw new ProviderError(error instanceof Error ? error.message : String(error), { startTime: providerStartTimeISO, endTime: providerEndTimeISO, duration: totalDuration, - } - - throw enhancedError + }) } }, } diff --git a/apps/sim/providers/groq/index.ts b/apps/sim/providers/groq/index.ts index bf253bc7d..cf3d45c78 100644 --- a/apps/sim/providers/groq/index.ts +++ b/apps/sim/providers/groq/index.ts @@ -10,6 +10,7 @@ import type { ProviderResponse, TimeSegment, } from '@/providers/types' +import { ProviderError } from '@/providers/types' import { calculateCost, prepareToolExecution, @@ -496,15 +497,11 @@ export const groqProvider: ProviderConfig = { duration: totalDuration, }) - const enhancedError = new Error(error instanceof Error ? error.message : String(error)) - // @ts-ignore - enhancedError.timing = { + throw new ProviderError(error instanceof Error ? error.message : String(error), { startTime: providerStartTimeISO, endTime: providerEndTimeISO, duration: totalDuration, - } - - throw enhancedError + }) } }, } diff --git a/apps/sim/providers/mistral/index.ts b/apps/sim/providers/mistral/index.ts index 0195c04fb..5b261c947 100644 --- a/apps/sim/providers/mistral/index.ts +++ b/apps/sim/providers/mistral/index.ts @@ -11,6 +11,7 @@ import type { ProviderResponse, TimeSegment, } from '@/providers/types' +import { ProviderError } from '@/providers/types' import { calculateCost, prepareToolExecution, @@ -551,15 +552,11 @@ export const mistralProvider: ProviderConfig = { duration: totalDuration, }) - const enhancedError = new Error(error instanceof Error ? error.message : String(error)) - // @ts-ignore - Adding timing property to error for debugging - enhancedError.timing = { + throw new ProviderError(error instanceof Error ? error.message : String(error), { startTime: providerStartTimeISO, endTime: providerEndTimeISO, duration: totalDuration, - } - - throw enhancedError + }) } }, } diff --git a/apps/sim/providers/ollama/index.ts b/apps/sim/providers/ollama/index.ts index 921c1afd0..f8485bdfe 100644 --- a/apps/sim/providers/ollama/index.ts +++ b/apps/sim/providers/ollama/index.ts @@ -12,6 +12,7 @@ import type { ProviderResponse, TimeSegment, } from '@/providers/types' +import { ProviderError } from '@/providers/types' import { calculateCost, prepareToolExecution } from '@/providers/utils' import { useProvidersStore } from '@/stores/providers' import { executeTool } from '@/tools' @@ -554,15 +555,11 @@ export const ollamaProvider: ProviderConfig = { duration: totalDuration, }) - const enhancedError = new Error(error instanceof Error ? error.message : String(error)) - // @ts-ignore - enhancedError.timing = { + throw new ProviderError(error instanceof Error ? error.message : String(error), { startTime: providerStartTimeISO, endTime: providerEndTimeISO, duration: totalDuration, - } - - throw enhancedError + }) } }, } diff --git a/apps/sim/providers/openai/core.ts b/apps/sim/providers/openai/core.ts index 6e6d42cb4..6833181dc 100644 --- a/apps/sim/providers/openai/core.ts +++ b/apps/sim/providers/openai/core.ts @@ -3,6 +3,7 @@ import type OpenAI from 'openai' import type { StreamingExecution } from '@/executor/types' import { MAX_TOOL_ITERATIONS } from '@/providers' import type { Message, ProviderRequest, ProviderResponse, TimeSegment } from '@/providers/types' +import { ProviderError } from '@/providers/types' import { calculateCost, prepareToolExecution, @@ -806,14 +807,10 @@ export async function executeResponsesProviderRequest( duration: totalDuration, }) - const enhancedError = new Error(error instanceof Error ? error.message : String(error)) - // @ts-ignore - Adding timing property to the error - enhancedError.timing = { + throw new ProviderError(error instanceof Error ? error.message : String(error), { startTime: providerStartTimeISO, endTime: providerEndTimeISO, duration: totalDuration, - } - - throw enhancedError + }) } } diff --git a/apps/sim/providers/openrouter/index.ts b/apps/sim/providers/openrouter/index.ts index 0444fc35e..edbed1b7c 100644 --- a/apps/sim/providers/openrouter/index.ts +++ b/apps/sim/providers/openrouter/index.ts @@ -10,11 +10,14 @@ import { supportsNativeStructuredOutputs, } from '@/providers/openrouter/utils' import type { + FunctionCallResponse, + Message, ProviderConfig, ProviderRequest, ProviderResponse, TimeSegment, } from '@/providers/types' +import { ProviderError } from '@/providers/types' import { calculateCost, generateSchemaInstructions, @@ -90,7 +93,7 @@ export const openRouterProvider: ProviderConfig = { stream: !!request.stream, }) - const allMessages = [] as any[] + const allMessages: Message[] = [] if (request.systemPrompt) { allMessages.push({ role: 'system', content: request.systemPrompt }) @@ -237,8 +240,8 @@ export const openRouterProvider: ProviderConfig = { output: currentResponse.usage?.completion_tokens || 0, total: currentResponse.usage?.total_tokens || 0, } - const toolCalls = [] as any[] - const toolResults = [] as any[] + const toolCalls: FunctionCallResponse[] = [] + const toolResults: Record[] = [] const currentMessages = [...allMessages] let iterationCount = 0 let modelTime = firstResponseTime @@ -352,7 +355,7 @@ export const openRouterProvider: ProviderConfig = { let resultContent: any if (result.success) { - toolResults.push(result.output) + toolResults.push(result.output!) resultContent = result.output } else { resultContent = { @@ -593,14 +596,11 @@ export const openRouterProvider: ProviderConfig = { } logger.error('Error in OpenRouter request:', errorDetails) - const enhancedError = new Error(error instanceof Error ? error.message : String(error)) - // @ts-ignore - enhancedError.timing = { + throw new ProviderError(error instanceof Error ? error.message : String(error), { startTime: providerStartTimeISO, endTime: providerEndTimeISO, duration: totalDuration, - } - throw enhancedError + }) } }, } diff --git a/apps/sim/providers/types.ts b/apps/sim/providers/types.ts index cb75153c5..2c59bfcc1 100644 --- a/apps/sim/providers/types.ts +++ b/apps/sim/providers/types.ts @@ -59,6 +59,7 @@ export interface FunctionCallResponse { result?: Record output?: Record input?: Record + success?: boolean } export interface TimeSegment { @@ -177,4 +178,21 @@ export interface ProviderRequest { previousInteractionId?: string } +/** + * Typed error class for provider failures that includes timing information. + */ +export class ProviderError extends Error { + timing: { + startTime: string + endTime: string + duration: number + } + + constructor(message: string, timing: { startTime: string; endTime: string; duration: number }) { + super(message) + this.name = 'ProviderError' + this.timing = timing + } +} + export const providers: Record = {} diff --git a/apps/sim/providers/vllm/index.ts b/apps/sim/providers/vllm/index.ts index 0df587264..5e704c654 100644 --- a/apps/sim/providers/vllm/index.ts +++ b/apps/sim/providers/vllm/index.ts @@ -6,11 +6,13 @@ import type { StreamingExecution } from '@/executor/types' import { MAX_TOOL_ITERATIONS } from '@/providers' import { getProviderDefaultModel, getProviderModels } from '@/providers/models' import type { + Message, ProviderConfig, ProviderRequest, ProviderResponse, TimeSegment, } from '@/providers/types' +import { ProviderError } from '@/providers/types' import { calculateCost, prepareToolExecution, @@ -98,7 +100,7 @@ export const vllmProvider: ProviderConfig = { baseURL: `${baseUrl}/v1`, }) - const allMessages = [] as any[] + const allMessages: Message[] = [] if (request.systemPrompt) { allMessages.push({ @@ -635,23 +637,11 @@ export const vllmProvider: ProviderConfig = { duration: totalDuration, }) - const enhancedError = new Error(errorMessage) - // @ts-ignore - enhancedError.timing = { + throw new ProviderError(errorMessage, { startTime: providerStartTimeISO, endTime: providerEndTimeISO, duration: totalDuration, - } - if (errorType) { - // @ts-ignore - enhancedError.vllmErrorType = errorType - } - if (errorCode) { - // @ts-ignore - enhancedError.vllmErrorCode = errorCode - } - - throw enhancedError + }) } }, } diff --git a/apps/sim/providers/xai/index.ts b/apps/sim/providers/xai/index.ts index 8138265a3..98cbf52c1 100644 --- a/apps/sim/providers/xai/index.ts +++ b/apps/sim/providers/xai/index.ts @@ -5,11 +5,13 @@ import type { StreamingExecution } from '@/executor/types' import { MAX_TOOL_ITERATIONS } from '@/providers' import { getProviderDefaultModel, getProviderModels } from '@/providers/models' import type { + Message, ProviderConfig, ProviderRequest, ProviderResponse, TimeSegment, } from '@/providers/types' +import { ProviderError } from '@/providers/types' import { calculateCost, prepareToolExecution, @@ -52,7 +54,7 @@ export const xAIProvider: ProviderConfig = { streaming: !!request.stream, }) - const allMessages: any[] = [] + const allMessages: Message[] = [] if (request.systemPrompt) { allMessages.push({ @@ -587,15 +589,11 @@ export const xAIProvider: ProviderConfig = { hasResponseFormat: !!request.responseFormat, }) - const enhancedError = new Error(error instanceof Error ? error.message : String(error)) - // @ts-ignore - Adding timing property to error for debugging - enhancedError.timing = { + throw new ProviderError(error instanceof Error ? error.message : String(error), { startTime: providerStartTimeISO, endTime: providerEndTimeISO, duration: totalDuration, - } - - throw enhancedError + }) } }, }