Skip to content

Commit 91c139f

Browse files
committed
fix: improve error handling and add internationalization support in Gemini CLI
1 parent 74eea8f commit 91c139f

File tree

1 file changed

+22
-17
lines changed

1 file changed

+22
-17
lines changed

src/api/providers/gemini-cli.ts

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import axios from "axios"
88
import { type ModelInfo, type GeminiCliModelId, geminiCliDefaultModelId, geminiCliModels } from "@roo-code/types"
99

1010
import type { ApiHandlerOptions } from "../../shared/api"
11+
import { t } from "../../i18n"
1112

1213
import { convertAnthropicContentToGemini, convertAnthropicMessageToGemini } from "../transform/gemini-format"
1314
import type { ApiStream } from "../transform/stream"
@@ -61,7 +62,7 @@ export class GeminiCliHandler extends BaseProvider implements SingleCompletionHa
6162
})
6263
}
6364
} catch (error) {
64-
throw new Error(`Failed to load OAuth credentials. Please authenticate first: ${error}`)
65+
throw new Error(t("common:errors.geminiCli.oauthLoadFailed", { error }))
6566
}
6667
}
6768

@@ -87,7 +88,7 @@ export class GeminiCliHandler extends BaseProvider implements SingleCompletionHa
8788
await fs.writeFile(credPath, JSON.stringify(this.credentials, null, 2))
8889
}
8990
} catch (error) {
90-
throw new Error(`Failed to refresh OAuth token: ${error}`)
91+
throw new Error(t("common:errors.geminiCli.tokenRefreshFailed", { error }))
9192
}
9293
}
9394
}
@@ -96,9 +97,6 @@ export class GeminiCliHandler extends BaseProvider implements SingleCompletionHa
9697
* Call a Code Assist API endpoint
9798
*/
9899
private async callEndpoint(method: string, body: any, retryAuth: boolean = true): Promise<any> {
99-
console.log(`[GeminiCLI] Calling endpoint: ${method}`)
100-
console.log(`[GeminiCLI] Request body:`, JSON.stringify(body, null, 2))
101-
102100
try {
103101
const res = await this.authClient.request({
104102
url: `${CODE_ASSIST_ENDPOINT}/${CODE_ASSIST_API_VERSION}:${method}`,
@@ -109,8 +107,6 @@ export class GeminiCliHandler extends BaseProvider implements SingleCompletionHa
109107
responseType: "json",
110108
data: JSON.stringify(body),
111109
})
112-
console.log(`[GeminiCLI] Response status:`, res.status)
113-
console.log(`[GeminiCLI] Response data:`, JSON.stringify(res.data, null, 2))
114110
return res.data
115111
} catch (error: any) {
116112
console.error(`[GeminiCLI] Error calling ${method}:`, error)
@@ -120,7 +116,6 @@ export class GeminiCliHandler extends BaseProvider implements SingleCompletionHa
120116

121117
// If we get a 401 and haven't retried yet, try refreshing auth
122118
if (error.response?.status === 401 && retryAuth) {
123-
console.log(`[GeminiCLI] Got 401, attempting to refresh authentication...`)
124119
await this.ensureAuthenticated() // This will refresh the token
125120
return this.callEndpoint(method, body, false) // Retry without further auth retries
126121
}
@@ -182,18 +177,26 @@ export class GeminiCliHandler extends BaseProvider implements SingleCompletionHa
182177

183178
let lroResponse = await this.callEndpoint("onboardUser", onboardRequest)
184179

185-
// Poll until operation is complete
186-
while (!lroResponse.done) {
180+
// Poll until operation is complete with timeout protection
181+
const MAX_RETRIES = 30 // Maximum number of retries (60 seconds total)
182+
let retryCount = 0
183+
184+
while (!lroResponse.done && retryCount < MAX_RETRIES) {
187185
await new Promise((resolve) => setTimeout(resolve, 2000))
188186
lroResponse = await this.callEndpoint("onboardUser", onboardRequest)
187+
retryCount++
188+
}
189+
190+
if (!lroResponse.done) {
191+
throw new Error(t("common:errors.geminiCli.onboardingTimeout"))
189192
}
190193

191194
const discoveredProjectId = lroResponse.response?.cloudaicompanionProject?.id || initialProjectId
192195
this.projectId = discoveredProjectId
193196
return this.projectId as string
194197
} catch (error: any) {
195198
console.error("Failed to discover project ID:", error.response?.data || error.message)
196-
throw new Error("Could not discover project ID. Make sure you're authenticated with 'gemini auth'.")
199+
throw new Error(t("common:errors.geminiCli.projectDiscoveryFailed"))
197200
}
198201
}
199202

@@ -261,8 +264,6 @@ export class GeminiCliHandler extends BaseProvider implements SingleCompletionHa
261264
requestBody.request.generationConfig.thinkingConfig = thinkingConfig
262265
}
263266

264-
console.log("[GeminiCLI] Request body:", JSON.stringify(requestBody, null, 2))
265-
266267
try {
267268
// Call Code Assist streaming endpoint using OAuth2Client
268269
const response = await this.authClient.request({
@@ -335,12 +336,16 @@ export class GeminiCliHandler extends BaseProvider implements SingleCompletionHa
335336
console.error("[GeminiCLI] Error Response:", error.response?.data)
336337

337338
if (error.response?.status === 429) {
338-
throw new Error("Rate limit exceeded. Free tier limits have been reached.")
339+
throw new Error(t("common:errors.geminiCli.rateLimitExceeded"))
339340
}
340341
if (error.response?.status === 400) {
341-
throw new Error(`Bad request: ${JSON.stringify(error.response?.data) || error.message}`)
342+
throw new Error(
343+
t("common:errors.geminiCli.badRequest", {
344+
details: JSON.stringify(error.response?.data) || error.message,
345+
}),
346+
)
342347
}
343-
throw new Error(`Gemini CLI API error: ${error.message}`)
348+
throw new Error(t("common:errors.geminiCli.apiError", { error: error.message }))
344349
}
345350
}
346351

@@ -400,7 +405,7 @@ export class GeminiCliHandler extends BaseProvider implements SingleCompletionHa
400405
return ""
401406
} catch (error) {
402407
if (error instanceof Error) {
403-
throw new Error(`Gemini CLI completion error: ${error.message}`)
408+
throw new Error(t("common:errors.geminiCli.completionError", { error: error.message }))
404409
}
405410
throw error
406411
}

0 commit comments

Comments
 (0)