Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 60 additions & 8 deletions src/api/providers/openrouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,10 +256,36 @@ export class OpenRouterHandler extends BaseProvider implements SingleCompletionH
try {
stream = await this.client.chat.completions.create(completionParams, requestOptions)
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error)
const apiError = new ApiProviderError(errorMessage, this.providerName, modelId, "createMessage")
TelemetryService.instance.captureException(apiError)
throw handleOpenAIError(error, this.providerName)
// Check if error has OpenRouter-specific metadata.raw property
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This error handling logic is nearly identical to the one in completePrompt. Consider extracting it into a shared helper function to reduce duplication.

This comment was generated because it violated a code review rule: irule_tTqpIuNs8DV0QFGj.

const errorObj = error as any
const hasMetadataRaw = errorObj?.metadata?.raw
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The property path errorObj?.metadata?.raw differs from how handleOpenAIError accesses the same property ((error as any)?.error?.metadata?.raw). Based on the OpenAISdkError interface in telemetry.ts, SDK exceptions typically have metadata nested under error.error. If that's the case for OpenRouter SDK errors, this check would always be falsy and the enhanced error handling would never execute. Worth verifying the actual error structure from OpenRouter - you may need errorObj?.error?.metadata?.raw instead.

Fix it with Roo Code or mention @roomote and request a fix.


if (hasMetadataRaw) {
const openRouterError = error as OpenRouterErrorResponse
const rawErrorMessage = openRouterError.metadata?.raw || openRouterError.message
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic seems a little overly defensive - is it possible for the raw error to not be present if hasMetadataRaw is truthy?


const apiError = Object.assign(
new ApiProviderError(
rawErrorMessage ?? "Unknown error",
this.providerName,
modelId,
"createMessage",
openRouterError.code,
),
{
status: openRouterError.code,
error: { message: openRouterError.message, metadata: openRouterError.metadata },
},
)

TelemetryService.instance.captureException(apiError)
throw handleOpenAIError(error, this.providerName)
} else {
const errorMessage = error instanceof Error ? error.message : String(error)
const apiError = new ApiProviderError(errorMessage, this.providerName, modelId, "createMessage")
TelemetryService.instance.captureException(apiError)
throw handleOpenAIError(error, this.providerName)
}
}

let lastUsage: CompletionUsage | undefined = undefined
Expand Down Expand Up @@ -476,10 +502,36 @@ export class OpenRouterHandler extends BaseProvider implements SingleCompletionH
try {
response = await this.client.chat.completions.create(completionParams, requestOptions)
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error)
const apiError = new ApiProviderError(errorMessage, this.providerName, modelId, "completePrompt")
TelemetryService.instance.captureException(apiError)
throw handleOpenAIError(error, this.providerName)
// Check if error has OpenRouter-specific metadata.raw property
const errorObj = error as any
const hasMetadataRaw = errorObj?.metadata?.raw

if (hasMetadataRaw) {
const openRouterError = error as OpenRouterErrorResponse
const rawErrorMessage = openRouterError.metadata?.raw || openRouterError.message

const apiError = Object.assign(
new ApiProviderError(
rawErrorMessage ?? "Unknown error",
this.providerName,
modelId,
"completePrompt",
openRouterError.code,
),
{
status: openRouterError.code,
error: { message: openRouterError.message, metadata: openRouterError.metadata },
},
)

TelemetryService.instance.captureException(apiError)
throw handleOpenAIError(error, this.providerName)
} else {
const errorMessage = error instanceof Error ? error.message : String(error)
const apiError = new ApiProviderError(errorMessage, this.providerName, modelId, "completePrompt")
TelemetryService.instance.captureException(apiError)
throw handleOpenAIError(error, this.providerName)
}
}

if ("error" in response) {
Expand Down
Loading