fix(cli): show Kilo Gateway login rate limit message

This commit is contained in:
Mohammad Javad Naderi
2026-06-30 16:37:17 +03:30
parent 069c8d1969
commit 654e10e25b
5 changed files with 98 additions and 3 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"@kilocode/cli": patch
---
Show the Kilo Gateway rate-limit message when login has too many pending authorization requests.
@@ -16,6 +16,7 @@ import { isConsoleManagedProvider } from "@tui/util/provider-origin"
import * as KiloProvider from "@/kilocode/cli/cmd/tui/component/dialog-provider" // kilocode_change
import { useConnected } from "./use-connected"
import { useBindings } from "../keymap"
import { errorMessage } from "@/util/error" // kilocode_change
const PROVIDER_PRIORITY: Record<string, number> = KiloProvider.PROVIDER_PRIORITY // kilocode_change
@@ -182,7 +183,7 @@ export function createDialogProviderOptions() {
if (result.error) {
toast.show({
variant: "error",
message: JSON.stringify(result.error),
message: errorMessage(result.error), // kilocode_change
})
dialog.clear()
return
+7 -1
View File
@@ -6,6 +6,7 @@ import { optionalOmitUndefined } from "@opencode-ai/core/schema"
import { Plugin } from "../plugin"
import { ProviderID } from "./schema"
import { Array as Arr, Effect, Layer, Record, Result, Context, Schema } from "effect"
import { errorMessage } from "@/util/error" // kilocode_change
// kilocode_change start
import { Telemetry } from "@kilocode/kilo-telemetry"
@@ -183,7 +184,12 @@ export const layer: Layer.Layer<Service, never, Auth.Service | Plugin.Service |
}
}
const result = yield* Effect.promise(() => method.authorize(input.inputs))
// kilocode_change start
const result = yield* Effect.tryPromise({
try: () => method.authorize(input.inputs),
catch: (err) => new Auth.AuthError({ message: errorMessage(err), cause: err }),
})
// kilocode_change end
pending.set(input.providerID, result)
return {
url: result.url,
@@ -30,7 +30,7 @@ function mapProviderAuthError<A, R>(self: Effect.Effect<A, ProviderAuth.Error, R
if (error instanceof ProviderAuth.ValidationFailed) {
return new ProviderAuthApiError({ name: error._tag, data: { field: error.field, message: error.message } })
}
return new ProviderAuthApiError({ name: "BadRequest", data: {} })
return new ProviderAuthApiError({ name: "BadRequest", data: { message: error.message } }) // kilocode_change
}),
)
}
@@ -0,0 +1,83 @@
import { expect } from "bun:test"
import { AppFileSystem } from "@opencode-ai/core/filesystem"
import { Effect, Layer } from "effect"
import path from "path"
import * as Log from "@opencode-ai/core/util/log"
import { Server } from "../../src/server/server"
import { resetDatabase } from "../fixture/db"
import { TestInstance } from "../fixture/fixture"
import { testEffect } from "../lib/effect"
import { preparePluginDependencies } from "./plugin-dependencies"
Log.init({ print: false })
const state = Layer.effectDiscard(
Effect.acquireRelease(
Effect.promise(() => resetDatabase()),
() => Effect.promise(() => resetDatabase()),
),
)
const it = testEffect(Layer.mergeAll(state, AppFileSystem.defaultLayer))
function writePlugin(dir: string) {
return Effect.gen(function* () {
const fs = yield* AppFileSystem.Service
yield* Effect.promise(() => preparePluginDependencies(dir))
yield* fs.writeWithDirs(
path.join(dir, ".kilo", "plugin", "provider-oauth-reject.ts"),
[
"export default {",
' id: "test.provider-oauth-reject",',
" server: async () => ({",
" auth: {",
' provider: "test-oauth-reject",',
" methods: [",
" {",
' type: "oauth",',
' label: "OAuth",',
" authorize: async () => {",
' throw new Error("Too many pending authorization requests. Please try again later.")',
" },",
" },",
" ],",
" },",
" }),",
"}",
"",
].join("\n"),
)
})
}
function authorize(input: { app: ReturnType<typeof Server.Default>["app"]; dir: string }) {
return Effect.promise(async () => {
const response = await input.app.request("/provider/test-oauth-reject/oauth/authorize", {
method: "POST",
headers: { "x-kilo-directory": input.dir, "content-type": "application/json" },
body: JSON.stringify({ method: 0 }),
})
return {
status: response.status,
body: await response.json(),
}
})
}
it.instance(
"returns plugin OAuth authorize rejection messages",
Effect.gen(function* () {
const instance = yield* TestInstance
yield* writePlugin(instance.directory)
const response = yield* authorize({ app: Server.Default().app, dir: instance.directory })
expect(response.status).toBe(400)
expect(response.body).toEqual({
name: "BadRequest",
data: { message: "Too many pending authorization requests. Please try again later." },
})
}),
{ config: { formatter: false, lsp: false } },
30000,
)