Skip to content

Commit bb8e75a

Browse files
authored
fix(resilience): surface Responses failed.error.message in 502s (#12472)
Validado em lote numa worktree combinada com os 10 PRs desta leva sobre o tip de `release/v3.8.51`: `typecheck:core` limpo, `check-file-size` OK e **241/242** nos 29 arquivos de teste que os PRs tocam. A única "falha" não é falha: `tests/unit/autoCombo/strict-zero-cost-filter.test.ts` é um teste em estilo Vitest que eu incluí por engano na invocação do runner nativo do Node — ele quebra no import (`@vitest/runner`), não numa asserção. Ao investigar, descobri que esse arquivo não roda em nenhum dos dois runners hoje (o glob do `test:unit` não lista `autoCombo` e o `include` do Vitest só pega `.tsx` nessa pasta); é um problema pré-existente do repositório, sem relação com esta leva, e vou registrá-lo separadamente. O #12636 conflitava apenas na lista de testes do `@omniroute/opencode-plugin/package.json`, de forma aditiva: o tip já tinha `models-fetcher.test.ts` (do #12607, irmão desta mesma leva) e o #12636 acrescenta `telemetry.test.ts`. Fiz a união dos dois lados (25 arquivos contra 24 de cada) em vez de escolher um, o que teria removido um arquivo da suíte do plugin em silêncio. Obrigado, @RaviTharuma.
1 parent 04ba19f commit bb8e75a

2 files changed

Lines changed: 23 additions & 1 deletion

File tree

open-sse/utils/diagnostics.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,8 +323,14 @@ export function describeMalformedNonStream(
323323
): { message: string; code: string; type: string } {
324324
const body = resp && typeof resp === "object" ? (resp as Record<string, unknown>) : null;
325325
if (body?.object === "response" && body.status === "failed") {
326+
const err = body.error && typeof body.error === "object" ? (body.error as Record<string, unknown>) : null;
327+
const rawMessage =
328+
typeof err?.message === "string" && err.message.trim().length > 0 ? err.message.trim() : null;
326329
return {
327-
message: "upstream reported a failed response without usable output",
330+
// Trim only here; buildErrorBody (chatCore) does the single sanitization pass.
331+
message: rawMessage
332+
? `upstream reported a failed response: ${rawMessage}`
333+
: "upstream reported a failed response without usable output",
328334
code: "upstream_response_failed",
329335
type: "upstream_response_error",
330336
};

tests/unit/diagnostics.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,22 @@ test("failed Responses API body gets a request-scoped machine-readable classific
105105
});
106106
});
107107

108+
test("failed Responses API body surfaces the upstream error message when present", () => {
109+
const failed = {
110+
object: "response",
111+
status: "failed",
112+
output: [],
113+
error: { code: "server_error", message: " Gemini 503: overloaded " },
114+
};
115+
const reason = detectMalformedNonStream(failed);
116+
assert.equal(reason, "empty_choices");
117+
assert.deepEqual(describeMalformedNonStream(failed, reason), {
118+
message: "upstream reported a failed response: Gemini 503: overloaded",
119+
code: "upstream_response_failed",
120+
type: "upstream_response_error",
121+
});
122+
});
123+
108124
test("detectMalformedNonStream returns 'empty_choices' when choice message has no content", () => {
109125
const body = {
110126
choices: [{ message: { content: "", tool_calls: null }, finish_reason: "stop" }],

0 commit comments

Comments
 (0)