mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-07 08:26:51 +00:00
feat: add telemetry error capture to xAI provider
- Import TelemetryService from @roo-code/telemetry - Import ApiProviderError from @roo-code/types - Capture exceptions to telemetry in createMessage() catch block - Capture exceptions to telemetry in completePrompt() catch block - Add tests verifying telemetry capture on errors Follows the same pattern as PR #10073 for OpenRouter.
This commit is contained in:
parent
bf81fa7237
commit
5b17cf1b66
2 changed files with 79 additions and 1 deletions
|
|
@ -11,6 +11,16 @@ vitest.mock("openai", () => {
|
|||
}
|
||||
})
|
||||
|
||||
const mockCaptureException = vitest.fn()
|
||||
|
||||
vitest.mock("@roo-code/telemetry", () => ({
|
||||
TelemetryService: {
|
||||
instance: {
|
||||
captureException: (...args: unknown[]) => mockCaptureException(...args),
|
||||
},
|
||||
},
|
||||
}))
|
||||
|
||||
import OpenAI from "openai"
|
||||
import type { Anthropic } from "@anthropic-ai/sdk"
|
||||
|
||||
|
|
@ -25,6 +35,7 @@ describe("XAIHandler", () => {
|
|||
// Reset all mocks
|
||||
vi.clearAllMocks()
|
||||
mockCreate.mockClear()
|
||||
mockCaptureException.mockClear()
|
||||
|
||||
// Create handler with mock
|
||||
handler = new XAIHandler({})
|
||||
|
|
@ -140,6 +151,66 @@ describe("XAIHandler", () => {
|
|||
await expect(handler.completePrompt("test prompt")).rejects.toThrow(`xAI completion error: ${errorMessage}`)
|
||||
})
|
||||
|
||||
describe("Telemetry Error Capture", () => {
|
||||
it("captures telemetry when createMessage throws an exception", async () => {
|
||||
const errorMessage = "Connection failed"
|
||||
mockCreate.mockRejectedValueOnce(new Error(errorMessage))
|
||||
|
||||
const generator = handler.createMessage("test prompt", [])
|
||||
await expect(generator.next()).rejects.toThrow()
|
||||
|
||||
expect(mockCaptureException).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
message: errorMessage,
|
||||
provider: "xAI",
|
||||
modelId: xaiDefaultModelId,
|
||||
operation: "createMessage",
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
it("captures telemetry when completePrompt throws an exception", async () => {
|
||||
const errorMessage = "API error"
|
||||
mockCreate.mockRejectedValueOnce(new Error(errorMessage))
|
||||
|
||||
await expect(handler.completePrompt("test prompt")).rejects.toThrow()
|
||||
|
||||
expect(mockCaptureException).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
message: errorMessage,
|
||||
provider: "xAI",
|
||||
modelId: xaiDefaultModelId,
|
||||
operation: "completePrompt",
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
it("captures telemetry with correct model ID when using a specific model", async () => {
|
||||
const specificModelHandler = new XAIHandler({ apiModelId: "grok-3" })
|
||||
const errorMessage = "Model error"
|
||||
mockCreate.mockRejectedValueOnce(new Error(errorMessage))
|
||||
|
||||
await expect(specificModelHandler.completePrompt("test prompt")).rejects.toThrow()
|
||||
|
||||
expect(mockCaptureException).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
message: errorMessage,
|
||||
provider: "xAI",
|
||||
modelId: "grok-3",
|
||||
operation: "completePrompt",
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
it("captures telemetry and still re-throws the error", async () => {
|
||||
const errorMessage = "Network error"
|
||||
mockCreate.mockRejectedValueOnce(new Error(errorMessage))
|
||||
|
||||
await expect(handler.completePrompt("test prompt")).rejects.toThrow(`xAI completion error: ${errorMessage}`)
|
||||
expect(mockCaptureException).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
})
|
||||
|
||||
it("createMessage should yield text content from stream", async () => {
|
||||
const testContent = "This is test content"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import OpenAI from "openai"
|
||||
|
||||
import { type XAIModelId, xaiDefaultModelId, xaiModels } from "@roo-code/types"
|
||||
import { type XAIModelId, xaiDefaultModelId, xaiModels, ApiProviderError } from "@roo-code/types"
|
||||
import { TelemetryService } from "@roo-code/telemetry"
|
||||
|
||||
import { NativeToolCallParser } from "../../core/assistant-message/NativeToolCallParser"
|
||||
import type { ApiHandlerOptions } from "../../shared/api"
|
||||
|
|
@ -79,6 +80,9 @@ export class XAIHandler extends BaseProvider implements SingleCompletionHandler
|
|||
try {
|
||||
stream = await this.client.chat.completions.create(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)
|
||||
}
|
||||
|
||||
|
|
@ -158,6 +162,9 @@ export class XAIHandler extends BaseProvider implements SingleCompletionHandler
|
|||
|
||||
return response.choices[0]?.message.content || ""
|
||||
} 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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue