fix: address Copilot review comments

- Read response.text() before JSON.parse to avoid double serialization
- Use text.slice(0, 500) instead of JSON.stringify(json).slice(0, 500)
- Add typeof content !== 'string' check for stronger type validation
- Add explicit JSON parse error handling with try/catch
This commit is contained in:
yuanzonghao
2026-05-31 12:57:22 +08:00
parent 10359d1a01
commit 4eb6c69af9
2 changed files with 18 additions and 12 deletions
+9 -6
View File
@@ -30,20 +30,23 @@ export async function chat(
body: JSON.stringify(body), body: JSON.stringify(body),
}); });
const text = await res.text();
if (!res.ok) { if (!res.ok) {
const text = await res.text();
throw new Error(`Chat API error ${res.status}: ${text}`); throw new Error(`Chat API error ${res.status}: ${text}`);
} }
const json = (await res.json()) as { let json: { choices: { message: { content: string } }[] };
choices: { message: { content: string } }[]; try {
}; json = JSON.parse(text);
} catch {
throw new Error(`Chat API returned invalid JSON: ${text.slice(0, 500)}`);
}
// Guard against empty choices array or missing message/content fields // Guard against empty choices array or missing message/content fields
const content = json.choices?.[0]?.message?.content; const content = json.choices?.[0]?.message?.content;
if (content === undefined || content === null) { if (typeof content !== "string") {
throw new Error( throw new Error(
`Chat API returned no content. Response: ${JSON.stringify(json).slice(0, 500)}` `Chat API returned no content. Response: ${text.slice(0, 500)}`
); );
} }
+9 -6
View File
@@ -45,20 +45,23 @@ export async function interpretClick(
clearTimeout(timeoutId); clearTimeout(timeoutId);
} }
const text = await res.text();
if (!res.ok) { if (!res.ok) {
const text = await res.text();
throw new Error(`Vision API error ${res.status}: ${text}`); throw new Error(`Vision API error ${res.status}: ${text}`);
} }
const json = (await res.json()) as { let json: { choices: { message: { content: string } }[] };
choices: { message: { content: string } }[]; try {
}; json = JSON.parse(text);
} catch {
throw new Error(`Vision API returned invalid JSON: ${text.slice(0, 500)}`);
}
// Guard against empty choices array or missing message/content fields // Guard against empty choices array or missing message/content fields
const content = json.choices?.[0]?.message?.content; const content = json.choices?.[0]?.message?.content;
if (content === undefined || content === null) { if (typeof content !== "string") {
throw new Error( throw new Error(
`Vision API returned no content. Response: ${JSON.stringify(json).slice(0, 500)}` `Vision API returned no content. Response: ${text.slice(0, 500)}`
); );
} }