fix(console): parse provider SSE error bodies

This commit is contained in:
opencode-agent[bot] 2026-06-02 12:48:06 +00:00
commit 1e1dc56a09
3 changed files with 61 additions and 1 deletions

View file

@ -48,6 +48,7 @@ import { localeFromRequest } from "~/lib/language"
import { createModelTpmLimiter } from "./modelTpmLimiter"
import { createModelTpsLimiter } from "./modelTpsLimiter"
import { accumulateUsage, HOT_WORKSPACES } from "./usageBatcher"
import { readProviderError } from "./providerError"
type ZenData = Awaited<ReturnType<typeof ZenData.list>>
type RetryOptions = {
@ -248,7 +249,7 @@ export async function handler(
// Handle non-streaming response
if (!isStream || [400, 404, 429].includes(res.status)) {
const json = await res.json()
const json = res.status === 200 ? await res.json() : await readProviderError(res)
await rateLimiter?.track()
const usage = providerInfo.extractUsage(json)
if (usage) {

View file

@ -0,0 +1,33 @@
export async function readProviderError(res: Response) {
const body = await res.text()
const json = parseJson(body)
if (json && typeof json === "object") return json as Record<string, any>
return parseProviderErrorBody(body, res.statusText)
}
export function parseProviderErrorBody(body: string, statusText: string) {
const text = body.trim()
const sseData = text
.split(/\r?\n/)
.map((line) => line.trim())
.filter((line) => line.startsWith("data:"))
.map((line) => line.slice(5).trim())
.filter((line) => line && line !== "[DONE]")
const parsed = sseData.map(parseJson).find((item) => item && typeof item === "object")
if (parsed) return parsed as Record<string, any>
return {
error: {
message: sseData[0] || text || statusText,
},
}
}
function parseJson(value: string) {
try {
return JSON.parse(value) as unknown
} catch {
return undefined
}
}

View file

@ -0,0 +1,26 @@
import { describe, expect, test } from "bun:test"
import { parseProviderErrorBody } from "../src/routes/zen/util/providerError"
describe("provider error parsing", () => {
test("parses SSE error bodies from upstream rate limits", () => {
expect(
parseProviderErrorBody(
'event:error\ndata: {"error":{"type":"rate_limit_error","message":"Too many requests"}}\n\n',
"Too Many Requests",
),
).toEqual({
error: {
type: "rate_limit_error",
message: "Too many requests",
},
})
})
test("wraps plain text errors in provider error shape", () => {
expect(parseProviderErrorBody("overloaded", "Too Many Requests")).toEqual({
error: {
message: "overloaded",
},
})
})
})